Skip to Content
Evaluate Get Started Plugins Glossary

Pluggable Security

Without pluggable security, a workflow engine must either manage its own users and roles - adding a second identity system to maintain - or hard-code authorization logic that cannot adapt to different deployments. Every transition, every command, needs a permission check, but the identity source changes from one organization to the next.

Pluggable security is a provider interface - IWorkflowRuleProvider - that delegates named workflow rule checks to your application code. Workflow Engine never stores passwords, manages users, or maintains role hierarchies. When the runtime evaluates a provider-backed transition restriction, it asks your code: "Can this person execute this command on this process instance?"

With pluggable security, you connect Workflow Engine to your existing identity system in one integration point. For example, a rule named "Manager" on an approval transition causes your provider to check whether the calling user belongs to the Manager group in Active Directory, Azure AD, or your own user table - whatever you implement.

What it is

Think of the rule provider as a security guard that your company trains. You teach the guard how to recognize authorized people - by checking your employee directory, your SSO system, your custom database - and the guard stands at every door (transition) and makes the call. Workflow Engine does not need to know how your directory works. It just asks the guard: "Is this person allowed through this door?"

When your application calls GetAvailableCommandsAsync, the runtime evaluates command transitions from the current activities of the process and its active subprocesses. For each provider-backed restriction, it asks the rule provider whether the supplied identity can pass. Commands whose restrictions do not pass are omitted. ExecuteCommandAsync does not repeat these checks by default; call ExecuteCommandWithRestrictionCheckAsync or pass checkRestrictions: true when command execution must repeat authorization.

The provider receives the user's identity ID, the rule name, and an optional parameter - typically a role name, a group name, or a permission string. The provider's job is to return true or false.

For developers: Implement IWorkflowRuleProvider, which has seven members: synchronous (GetRules, Check, GetIdentities) and asynchronous variants (CheckAsync, GetIdentitiesAsync), plus IsCheckAsync and IsGetIdentitiesAsync to declare which variant the runtime should use. Register the implementation with runtime.WithRuleProvider(new MyRuleProvider()). The Check / CheckAsync methods receive the process instance, the runtime reference, the user's identity ID, the rule name, and an optional parameter string. See Rule for a complete scheme example and an IWorkflowRuleProvider implementation.

Why it matters

Pluggable security delivers these outcomes:

  • Your identity system stays in charge - No user synchronization, no password storage, no role duplication. Workflow Engine never becomes a second source of truth for who can do what. A user removed from a group in your directory fails the next check your provider makes.
  • One integration point for provider-backed rules - Implement one interface and every transition restriction that uses one of its rule names calls it. There is no per-transition or per-activity rule code to scatter across your integration.
  • Works with any identity provider - Active Directory, Azure AD, Okta, Auth0, LDAP, a custom SQL database, a REST API - if your application code can query it, your rule provider can use it. The Active Directory plugin on the Plugins page is a ready implementation.
  • No lock-in to the provider choice - Swap from LDAP to Azure AD by replacing the rule provider implementation. No scheme changes, no model changes, no database changes. The runtime only depends on the interface, not the implementation.

Who it is for

Developer: You implement a single interface (IWorkflowRuleProvider) with a Check method that queries your identity system. Register it with runtime.WithRuleProvider(). The runtime calls your provider when it evaluates a transition restriction that uses one of the provider's rule names. See the Rules concept page for code examples and the DeactivatedWorkflowRuleProvider wrapper for toggling providers on and off at runtime.

Enterprise architect: The rule provider interface is the authorization integration point for transition restrictions that use named rules. Combined with the HTTP API or Web API, you can deploy Workflow Engine with no direct access to your identity infrastructure - only the provider implementation knows how to reach Active Directory or Azure AD. Audit rule evaluations by wrapping a logging provider around your real implementation.

When to use it

Use pluggable security in any deployment that needs command-level authorization - which is almost every deployment. Typical scenarios:

  • Role-based transitions on a purchase approval process - Only users in the "Manager" role can approve requisitions above $5,000. The rule provider checks the user's role memberships against the rule name on each transition.
  • Group-based document review - Only members of the "Legal Review" group can advance a contract to the signature stage. The scheme designer creates a rule named "LegalReviewGroup" and the provider resolves it against the identity system.
  • User-level self-service - Only the original requestor can cancel their own expense report. The provider checks the identity ID from the user context against a process parameter that stores the requestor ID.
  • Integration with an existing custom auth system - Your application has a custom permissions table with fine-grained resource-level access. The rule provider queries that table using the rule name (which encodes a permission key) and the optional parameter (which encodes the resource scope).

How it compares

The table below compares Workflow Engine's pluggable security approach with the alternative of built-in user management in the engine.

Comparison of security approaches
ApproachWhat it requiresResult
Built-in user management in the engineThe engine stores users, roles, and passwords. User lifecycle (onboarding, offboarding, role changes) must be managed in two places. Password policies, MFA, and SSO integration become the engine's problem.Two identity systems to maintain. The engine must be kept secure as a user store.
Workflow Engine pluggable securityImplement IWorkflowRuleProvider. Register it with runtime.WithRuleProvider(). The engine delegates every authorization check to your code.One identity system - yours. No user data in the engine.

Frequently asked questions

What identity systems does Workflow Engine support?

Any system your application code can query - Active Directory, Azure AD, Okta, Auth0, LDAP, a custom SQL database, a REST API - through the IWorkflowRuleProvider interface. There is no built-in user store, no login page, no password validation. Workflow Engine does not impose a specific identity provider. The Active Directory plugin on the Plugins page is an out-of-box implementation.

How does Workflow Engine know who the current user is?

The caller supplies the user's identity ID when listing or executing commands with runtime methods such as GetAvailableCommandsAsync and ExecuteCommandAsync. In an ASP.NET Core application, you typically extract this from HttpContext.User.Identity.Name or a JWT claim and pass it to the API calls. Workflow Engine does not read HttpContext - command-related API calls receive the identity explicitly.

When are rules evaluated during process execution?

GetAvailableCommandsAsync checks the rules: it returns only the commands whose transition restrictions pass for the identity you supply. ExecuteCommandAsync does not check the restrictions again by default. To repeat the check when the command runs, call ExecuteCommandWithRestrictionCheckAsync or pass checkRestrictions: true. A transition without restrictions is available to every user. If a referenced rule name is not implemented by any provider or code action, the runtime throws NotImplementedException.

Can I have multiple rule providers registered at the same time?

Yes. Each call to WithRuleProvider adds the provider to an aggregating rule provider. For each rule name, the runtime asks one provider: the most recently registered provider that lists that rule for the scheme. The answer of that provider is the result; answers of several providers are not combined. To compose providers, give each provider its own rule names, or register a provider for specific schemes with the schemes argument of WithRuleProvider.

See also