---
title: Virtual roles
slug: cms-11/dev-docs/virtual-roles
docTags: 
createdAt: 2026-07-22T19:45:19.315Z
---

Optimizely Content Management System (CMS) uses an extension of the Role concept called *Virtual Roles* and determines a role's membership criteria at runtime. The virtual role membership is not stored in the database but depends on programmatic criteria that can vary with each request.

Virtual roles are controlled by the `<virtualRoles>` configuration element in the `<episever.framework>` section in `web.config`. A typical configuration looks like this:

```xml
<virtualRoles addClaims="true">
  <providers>
     <add name="Administrators" type="EPiServer.Security.WindowsAdministratorsRole, EPiServer" />
     <add name="Everyone" type="EPiServer.Security.EveryoneRole, EPiServer" />
     <add name="Authenticated" type="EPiServer.Security.AuthenticatedRole, EPiServer" />
     <add name="Anonymous" type="EPiServer.Security.AnonymousRole, EPiServer" />
     <add name="PackagingAdmins" type="EPiServer.Security.MappedRole, EPiServer.Framework" roles="WebAdmins, Administrators" mode="Any" />
     <add name="CmsAdmins" type="EPiServer.Security.MappedRole, EPiServer" roles="WebAdmins, Administrators" mode="Any" />
     <add name="CmsEditors" type="EPiServer.Security.MappedRole, EPiServer" roles="WebEditors" mode="Any" />
     <add name="Creator" type="EPiServer.Security.CreatorRole, EPiServer" />
     <add name="SearchAdmins" type="EPiServer.Security.MappedRole, EPiServer.Framework" roles="WebAdmins, Administrators" mode="Any" /> 
     <add name="SearchEditors" type="EPiServer.Security.MappedRole, EPiServer.Framework" roles="WebAdmins, Administrators" mode="Any" /> 
  </providers>
</virtualRoles>
```

Virtual roles can operate in two modes. By default, the `addClaims` attribute sets whether it adds a claim to the current principal for each virtual role in which a user is a member. If you set `replacePrincipal` to true, then the principal object gets replaced with a principal object wrapper that supports virtual roles by overriding the `IsInRole` method. CMS does not support this mode with federated security or other scenarios where claims are used because the wrapper is not claims-aware.

You can access the current principal object in several different ways. The recommended approach is to use `EPiServer.Security.PrincipalInfo.CurrentPrincipal` property. Alternate ways, such as `System.Web.HttpContext.Current.User`, are supported also.

If  `replacePrincipal="false"` and `addClaims="false"` then virtual roles are only evaluated when you check access rights based on ACLs in CMS. Any `principal.IsInRole` calls for a virtual role returns `false`.

The `<providers>` element contains a series of `<add...>` tags. Each `<add...>` defines a virtual role implementation (as identified by the type attribute) and gives the role a name with the name attribute.

CMS has the following virtual roles:

- Anonymous
- Authenticated
- Creator
- Everyone
- Administrator
- CmsAdmins
- CmsEditors
- PackagingAdmins
- SearchAdmins
- SearchEditors

In addition to the predefined roles, you can create virtual roles to allow access based on business rules, such as allowing access only during business hours. A common scenario is to define virtual roles that evaluate to true if the user is a member of *role1* and *role2*, which can reduce the number of groups needed for setting the required permissions in CMS.

- **Administrator** – Needed to support localized versions of Windows, where the Administrators group was translated. The administrator virtual role runs a localization-independent test for the administrator group, thus eliminating the need to modify manually`web.config` or access rights in CMS.
- **Creator** – Only used when evaluating `AccessControlLists` in CMS and returns true if the current principal is the same as the Creator for an ACL.
- **PackagingAdmins** – Used for controlling access to the **Add-ons** menu option from where you manage apps (add-ons).
- **SearchAdmins** – Used for controlling access to the Episerver Find user interface and the **Clear Indexes** page. Optimizely Search & Navigation users who are not Administrators must be WebEditors *and* SearchAdmins: WebEditors to access the edit view and SearchAdmins to access Optimizely Search & Navigation features.
- **SearchEditors** – Used to control access to the Optimizely Search & Navigation user interface. SearchEditors do *not* have access to the **Clear Indexes** page.

The **PackagingAdmins, CmsAdmins**, **CmsEditors, SearchEditors** and **SearchAdmins** virtual roles are of the `MappedRole` type (used to map existent or non-existent groups to several other groups). The roles attribute contains the names of one or more roles you use to evaluate membership in the `MappedRole`. The mode attribute can have the following values:

- **Any**  – membership in at least one of the roles listed in the roles attribute is required for membership in the mapped role.
- **All**  – membership in all roles listed in the roles attribute is required for membership in the mapped role.

## Register virtual roles programmatically

You can register virtual roles programmatically:

```csharp
[InitializableModule]
[ModuleDependency((typeof (EPiServer.Web.InitializationModule)))]
public class VirtualRoleInitializer: IInitializableModule {
  public void Initialize(InitializationEngine context) {
    var virtualRoleRepository = VirtualRoleRepository<VirtualRoleProviderBase>.GetDefault();
    virtualRoleRepository.Register("MyVirtualRoleType", new MyVirtualRoleType());
  }

  public void Uninitialize(InitializationEngine context) {}
  public void Preload(string[] parameters) {}
}
```
