# Role-Based Authorization Restrict command execution to users in specific roles using the `CheckRole` rule. This pattern enforces role-based access control in workflows, ensuring that only authorized users can perform sensitive actions like approvals, escalations, or administrative tasks. ## Real-world scenario A loan approval workflow requires that only users in the "Managers" role can approve loan applications. When a loan application reaches the approval activity, the workflow checks if the current user belongs to the "Managers" role before allowing them to execute the approval command. Users without this role see the activity but cannot execute the approval command. This ensures compliance with regulatory requirements and internal policies. ## Workflow scheme ![Role-based authorization workflow scheme](https://docs.workflowengine.io/images/plugins/basic-plugin/role-based-authorization/role-based-auth.png) **Related capabilities:** `CheckRole` rule, `UsersInRoleAsync` delegate. ```xml filename="role-based-auth.xml" {7-10,55-58} ``` ## Configuration Configure the `UsersInRoleAsync` delegate to resolve role membership from your data store: ```csharp basicPlugin.UsersInRoleAsync = async (role, processInstance) => { var users = await userRepository.GetUsersInRoleAsync(role); return users.Select(u => u.Id.ToString()); }; ``` Then create an actor in your scheme with `Rule: CheckRole` and `Value: Managers`. Add a restriction to a command transition with that actor and `Type: Allow`. Only users in the "Managers" role can execute the command. When `UsersInRoleAsync` is not set, `BasicPlugin` removes `CheckRole` from its rule provider. This does not invalidate the XML scheme during parsing or build because those stages do not verify provider rule availability. If no other provider or code action implements `CheckRole`, authorization throws `NotImplementedException` with `Rule with name CheckRole is not implemented` when it evaluates the restriction. ## Reference The following rule is available for role-based authorization. ### CheckRole rule Checks whether the current identity belongs to a specified role by calling the `UsersInRoleAsync` delegate. Use as a restriction on command transitions to limit execution to users in specific roles. Within `BasicPlugin`, the rule passes the actor `Value` it receives directly to `UsersInRoleAsync(roleName, processInstance)`. It does not normalize the value or compare role names. The application-provided delegate and its data store define role matching, including case sensitivity. If the delegate returns the user's identity ID, the user is allowed to execute the command. ## Troubleshooting common errors - **Actor `Value` does not resolve the expected role** - `BasicPlugin` passes the value directly to `UsersInRoleAsync` without comparing or normalizing it. Whether `"managers"` matches `"Managers"` depends on the delegate and its data store. Apply any required normalization or comparison rules in the application-provided delegate. - **Restriction references a non-existent actor** - if a restriction has `NameRef="Manager"` but no actor with `Name="Manager"` is defined in the scheme, parsing fails with `SchemeNotValidException` (`Actor Manager not found`). The invalid scheme does not reach command authorization. - **Multiple restrictions behave as AND, not OR** - when you add several Allow restrictions to a transition, all must pass by default (`AllowConcatenationType="And"`). To require only one matching role, set `AllowConcatenationType="Or"` on the transition element. ## See also - [Basic Plugin Overview](https://docs.workflowengine.io/plugins/basic-plugin/overview/): Registration, configuration, and full API reference. - [Parallel Approval](https://docs.workflowengine.io/plugins/basic-plugin/parallel-approval/): Set up multi-user approval without explicit branches. ## Frequently asked questions **How does the CheckRole rule work?** The `CheckRole` rule checks if the current user belongs to a specified role by calling the `UsersInRoleAsync` delegate. If the delegate returns the user's ID, the user is allowed to execute the command. If the user is not in the role, the command is blocked. **Can I use multiple roles for a single command?** Yes. Create multiple actors with different role values, then add multiple restrictions to the command transition. By default, restrictions use AND logic - the user must belong to all listed roles. To require only one role, set `AllowConcatenationType="Or"` on the transition element. **What happens if UsersInRoleAsync is not configured?** If `UsersInRoleAsync` is not set, the `CheckRole` rule is not registered with the workflow runtime. Any workflow scheme that references this rule can still parse and build. If no other implementation supplies `CheckRole`, the failure occurs later when authorization evaluates the restriction, with `Rule with name CheckRole is not implemented`. Configure the delegate before executing role-restricted commands. **Can I check role membership dynamically at runtime?** Yes. The `UsersInRoleAsync` delegate receives the process instance as a parameter, so you can access process parameters or other context to determine role membership dynamically. For example, you could check a "Department" parameter to determine which department managers have approval authority.