Predefined Actors
Register predefined actor names globally or for selected scheme codes, resolve their identities through BasicPlugin delegates, and use the runtime-injected actors in command transition restrictions. Keep actor membership in application code so authorization can change without copying identity lists into workflow schemes.
Predefined actors are BasicPlugin actor definitions registered in application code and injected into matching workflow schemes by WorkflowRuntime. Register actor names with WithActor or WithActors, resolve their identities with the plugin delegates, then select the injected actor in an Allow restriction on a command transition.
Prerequisites:
- Basic Plugin Overview - BasicPlugin registration and configuration.
- Workflow Runtime configuration - builder, persistence provider, startup, and shutdown configuration.
Real-world scenario
A document management system uses separate schemes for invoices, contracts, and other document types. Each process instance stores the document owner's identity in a persistent AuthorId parameter, while the application identity system assigns the Manager role independently of any document.
Without predefined actors, every document scheme would need separate actor definitions that check the Manager role and determine the current document author. Register Managers and DocumentAuthor for all schemes with one WithActors call instead. The BasicPlugin callbacks resolve Managers through the role directory and resolve DocumentAuthor from the current process instance.
Workflow scheme
The InvoiceApproval scheme restricts Submit to the document author and restricts Approve to managers. A ContractApproval scheme can use the same predefined actor names without copying their rule configuration.

Related capabilities: WithActor, WithActors, Predefined rule, CheckPredefinedActorAsync delegate.
<Process Name="InvoiceApproval" CanBeInlined="false"> <Designer /> <Parameters> <Parameter Name="AuthorId" Type="String" Purpose="Persistence" /> </Parameters> <Commands> <Command Name="Submit" /> <Command Name="Approve" /> </Commands> <Activities> <Activity Name="Draft" State="Draft" IsInitial="True" IsFinal="False" IsForSetState="True" IsAutoSchemeUpdate="True"> <Designer X="100" Y="200" /> </Activity> <Activity Name="AwaitingApproval" State="AwaitingApproval" IsInitial="False" IsFinal="False" IsForSetState="True" IsAutoSchemeUpdate="True"> <Designer X="450" Y="200" /> </Activity> <Activity Name="Approved" State="Approved" IsInitial="False" IsFinal="True" IsForSetState="True" IsAutoSchemeUpdate="True"> <Designer X="850" Y="200" /> </Activity> </Activities> <Transitions> <Transition Name="Draft_AwaitingApproval" To="AwaitingApproval" From="Draft" Classifier="Direct" IsFork="false" MergeViaSetState="false" DisableParentStateControl="false"> <Restrictions> <Restriction Type="Allow" NameRef="DocumentAuthor" /> </Restrictions> <Triggers> <Trigger Type="Command" NameRef="Submit" /> </Triggers> <Conditions> <Condition Type="Always" /> </Conditions> <Designer /> </Transition> <Transition Name="AwaitingApproval_Approved" To="Approved" From="AwaitingApproval" Classifier="Direct" IsFork="false" MergeViaSetState="false" DisableParentStateControl="false"> <Restrictions> <Restriction Type="Allow" NameRef="Managers" /> </Restrictions> <Triggers> <Trigger Type="Command" NameRef="Approve" /> </Triggers> <Conditions> <Condition Type="Always" /> </Conditions> <Designer /> </Transition> </Transitions></Process>The XML declares AuthorId, activities, commands, and restrictions, but it does not declare the predefined actors. WorkflowRuntime injects DocumentAuthor and Managers before parsing the restrictions. After BasicPlugin is registered, open the scheme in the Designer, enable Show predefined actors, and select the injected actor in each restriction.
Configure predefined actors
Configure actor names, scheme scopes, and identity delegates before passing BasicPlugin to WorkflowRuntime.WithPlugin. The registration determines which actor definitions the runtime injects into each loaded scheme.
Register actor names
BasicPlugin stores predefined actor names separately from the scheme. WithActor registers one name, while WithActors registers several names. Configure the names and identity delegates before passing the plugin to WorkflowRuntime.WithPlugin.
using System;using System.Collections.Generic;using System.Threading.Tasks;using OptimaJet.Workflow.Plugins;public interface IUserDirectory{ Task<bool> IsInRoleAsync( string identityId, string roleName); Task<IEnumerable<string>> GetUsersInRoleAsync( string roleName);}public static class PredefinedActorsConfiguration{ public static BasicPlugin CreateBasicPlugin( IUserDirectory userDirectory) { var basicPlugin = new BasicPlugin(); basicPlugin.WithActors(["Managers", "DocumentAuthor"]); basicPlugin.CheckPredefinedActorAsync = async (processInstance, runtime, actorName, identityId) => { if (actorName == "Managers") { return await userDirectory.IsInRoleAsync( identityId, "Manager"); } if (actorName == "DocumentAuthor") { string authorId = await processInstance .GetParameterAsync<string>("AuthorId"); return string.Equals( authorId, identityId, StringComparison.Ordinal); } return false; }; basicPlugin.GetPredefinedIdentitiesAsync = async (processInstance, runtime, actorName) => { if (actorName == "Managers") { return await userDirectory .GetUsersInRoleAsync("Manager"); } if (actorName == "DocumentAuthor") { string authorId = await processInstance .GetParameterAsync<string>("AuthorId"); return string.IsNullOrEmpty(authorId) ? [] : [authorId]; } return []; }; return basicPlugin; }}Pass the returned BasicPlugin instance to runtime.WithPlugin(...) within the complete WorkflowRuntime configuration. The runtime configuration guide shows the required builder and persistence provider setup before StartAsync().
CheckPredefinedActorAsync checks one identity during rule authorization. BasicPlugin passes the registered actor name in the third string position and the identity ID in the fourth string position, which is why the example names those lambda arguments actorName and identityId. GetPredefinedIdentitiesAsync returns the same manager role members or the AuthorId belonging to the current document process. Configure both callbacks when the application checks individual identities and enumerates workflow participants.
Choose actor scope
The schemes argument on WithActor and WithActors controls which scheme codes receive a predefined actor. A missing or empty list registers the actor for every scheme; a non-empty list limits the actor to the listed scheme codes.
| Registration | Resulting scope |
|---|---|
WithActor("Managers") | Managers is available to every scheme |
WithActors(names) | Every name is available to every scheme |
WithActor("DocumentAuthor", schemes) | DocumentAuthor is available only to the listed scheme codes |
WithActors(names, schemes) | Every name is available only to the listed scheme codes |
WorkflowRuntime combines the all-scheme names with the names registered for the current scheme code. Do not register the same actor name in both scopes for one scheme: duplicate predefined names cause GetPredefinedActors to throw ArgumentException while the scheme is loaded.
Predefined actor reference
WorkflowRuntime converts matching registrations into predefined actor definitions and uses the BasicPlugin callbacks to authorize identities. The provider API also supports applications that need to update registered actor collections explicitly.
Generated actor definitions
WorkflowRuntime creates an actor definition for every matching registered name before it parses transitions. The generated definition uses the registered name for both Name and Value, assigns the Predefined rule, and sets IsPredefined to true. Do not add a second actor with that name to the scheme.
Runtime authorization
For a command transition such as Approve, configure the restriction in the Designer as follows:
| Transition setting | Value |
|---|---|
| Trigger | Command |
| Command | Approve |
| Restriction type | Allow |
| Actor | Managers |
The Predefined rule is excluded from the ordinary Designer rule list, but it remains available to runtime authorization. Select the injected Managers actor in the restriction instead of creating a manual actor or choosing CheckRole. When a user requests the command, the Predefined rule calls CheckPredefinedActorAsync with Managers and that user's identity ID.
Actor provider operations
PredefinedActorProvider exposes the thread-safe IActorProvider API behind the convenience methods. Use WithActor and WithActors for initial configuration; use the provider when the application needs explicit read, replace, merge, add, or remove operations grouped by scheme code.
| Member | Operation |
|---|---|
GetAllActors | Returns copies of all actor collections grouped by scheme code |
SetAllActors | Replaces all grouped actor collections |
UnionAllActors | Merges actor collections into their matching scheme groups |
GetActors and SetActors | Reads or replaces the collection for one scheme code |
AddActor and AddActors | Adds one or more names to one scheme group |
RemoveActor and RemoveActors | Removes one or more names from one scheme group |
IsActorExist | Checks whether one scheme group contains an actor name |
The BasicPlugin API reference lists the public plugin members. Actor registration methods are intended for configuration before BasicPlugin is initialized by WorkflowRuntime.
Verify actor authorization
WorkflowRuntime injects a scheme-specific predefined actor only when the loaded scheme code matches its registration. Open the matching scheme in the Designer, enable Show predefined actors, and confirm that the actor appears as predefined. Then request the commands available to a known identity. A matching identity receives the restricted command; an identity for which CheckPredefinedActorAsync returns false does not.
Participant-enumeration APIs call GetPredefinedIdentitiesAsync instead of the single-identity check. Verify that this callback returns the same identity set represented by CheckPredefinedActorAsync, so command authorization and participant lists remain consistent.
Troubleshooting common errors
Predefined actor failures usually come from actor scope, duplicate names, or an unassigned BasicPlugin delegate. Match the observed symptom to the corresponding registration step.
| Symptom | Cause | Fix |
|---|---|---|
| A predefined actor is absent from a scheme | The scheme code is not in the actor scope, or BasicPlugin was registered after the scheme was loaded | Match the exact scheme code and register BasicPlugin during runtime configuration |
| Authorization fails when the rule runs | CheckPredefinedActorAsync is not configured | Assign the single-identity callback before registering BasicPlugin |
| Participant enumeration fails | GetPredefinedIdentitiesAsync is not configured | Assign the identity-enumeration callback before registering BasicPlugin |
| Scheme loading reports a duplicate predefined actor | The same name is registered for all schemes and for the current scheme | Keep the actor in only one applicable scope |
Predefined is missing from the rule dropdown | BasicPlugin intentionally excludes the system rule from ordinary choices | Select the runtime-injected actor in the transition restriction |
See also
Basic Plugin Overview
Register BasicPlugin and review its actions, conditions, rules, and configuration API.
Role-Based Authorization
Restrict commands by resolving identities through application roles.
Rule
Understand how actors connect transition restrictions to authorization checks.
Pluggable Security
Connect workflow authorization to an existing identity system.
Frequently asked questions
Do I add predefined actors to the workflow scheme?
No. WorkflowRuntime injects predefined actors registered by BasicPlugin while it parses the scheme. Reference the injected actor from a transition restriction instead of declaring a duplicate actor in the scheme.
Can a predefined actor be limited to one workflow scheme?
Yes. Pass the applicable scheme codes to WithActor or WithActors. Passing no scheme list, or an empty list, makes the predefined actor available to every scheme.
Which predefined actor delegates should I configure?
Configure CheckPredefinedActorAsync for single-identity authorization and GetPredefinedIdentitiesAsync for participant enumeration. Configure both when the application uses both runtime paths.
Why is the Predefined rule missing from the Designer rule list?
BasicPlugin excludes Predefined from ordinary rule choices because WorkflowRuntime assigns it to injected actor definitions. The rule remains registered for runtime authorization.
How are predefined actors different from CheckRole actors?
Predefined actors map application-defined names to identities through the two predefined actor delegates. CheckRole actors pass a role value to UsersInRoleAsync; see Role-Based Authorization for that pattern.