Multitenancy
Multitenancy lets you serve multiple tenants from one Workflow Engine deployment. Workflow Engine Web API maps one or more logical tenant IDs to each physical tenant runtime and provider. This supports physical, logical, and hybrid models. The request header or default selects a logical ID, and the request snapshot resolves its runtime and provider while Data API and RPC API operations stay in that tenant context.
Without multitenancy, every customer or business unit needs its own deployment of Workflow Engine - its own application, its own database, its own monitoring. That model becomes expensive and hard to operate as you add customers. Every new client means provisioning another environment, applying another set of upgrades, and managing another set of backups.
Multitenancy lets a single Workflow Engine deployment serve many customers or business units (tenants) from one application instance. Tenant separation works at two levels:
- Physical tenancy - each tenant gets its own database and its own
WorkflowRuntimeinstance. Full isolation at the persistence layer. Suitable for SaaS platforms where each client must have an independent database. - Logical tenancy - tenants share the same
WorkflowRuntimeand database. Tenant-aware persistence records are isolated byTenantId. Suitable for multi-division enterprise deployments where operational simplicity is more important than physical database separation.
The Workflow Engine Web API supports both levels and a hybrid model. Each registered physical tenant owns a runtime and data provider, and can serve one or more logical tenant IDs.
With multitenancy, you can add new customers without duplicating infrastructure. For example, a SaaS document approval platform can host workflows for dozens of client organizations from one application - each client gets isolated data, but the operations team manages a single deployment.
What it is
Multitenancy is like an apartment building. All tenants share the same building entrance and hallways (the application), but each apartment has its own lock and its own mailbox. Depending on your model, either each apartment has its own building (physical - separate database per tenant) or each apartment has its own locked box inside the same building (logical - TenantId filtering in shared storage). A hybrid model gives some tenants separate buildings while other tenants share one building.
The tenant identifier is a string value set when a process instance is created:
var createParams = new CreateInstanceParams{ SchemeCode = "OrderApproval", TenantId = "acme-corp", IdentityId = "user-42"};await runtime.CreateInstanceAsync(createParams);The TenantId is stored as a system parameter on every process instance. It is automatically propagated to subprocesses and persisted with tenant-aware process data, including statuses, parameters, timers, transition history, inbox entries, and approval history.
Workflow Engine Web API uses the selected logical tenant ID for Data API filtering and strict RPC API validation. A process from another logical tenant is not exposed to the caller. The tenant header selects context; API permissions separately determine whether the caller may access that tenant.
Physical tenancy (HTTP API)
In the HTTP API layer, each physical tenant has its own WorkflowRuntime instance and data provider. The IWorkflowTenantLocator resolves which physical tenant to use for each request based on the Workflow-Api-Tenant-ID HTTP header and the request-scoped tenant snapshot.
The header name is defined as the constant WorkflowApiConstants.TenantIdHeader. A request without the header is rejected with WorkflowTenantIdNotProvidedException (unless a default tenant is configured).
// Program.cs - configure tenants with separate databasesbuilder.Services.AddWorkflowApiCore(options =>{ options.DefaultTenantId = null; // Require header on every request});builder.Services.AddWorkflowTenants( new WorkflowTenantCreationOptions { TenantIds = ["acme-corp"], ConnectionString = "Server=db-acme;Database=Workflow;...", PersistenceProviderId = PersistenceProviderId.Mssql }, new WorkflowTenantCreationOptions { TenantIds = ["globex"], ConnectionString = "Server=db-globex;Database=Workflow;...", PersistenceProviderId = PersistenceProviderId.Mssql });Each IWorkflowTenant holds one WorkflowRuntime, one IDataProvider, and one or more logical tenant IDs. The snapshot maps every logical ID to its physical tenant, and the locator resolves that mapping for each HTTP request.
Logical tenancy (Core runtime and HTTP API)
In the logical model, one WorkflowRuntime and data provider serve multiple tenant IDs. Core operations use the TenantId parameter on CreateInstanceParams and tenant-aware persistence records for data isolation. In Workflow Engine Web API, list multiple IDs in one WorkflowTenantCreationOptions.TenantIds array. Requests for those IDs resolve to the same IWorkflowTenant, while the selected ID scopes Data API and RPC API operations. Your action and rule code can read processInstance.TenantId to make tenant-specific decisions:
public async Task ExecuteActionAsync(string name, ProcessInstance process, WorkflowRuntime runtime, string parameter, CancellationToken token){ var tenantId = process.TenantId; // Use tenantId to load tenant-specific configuration}Hybrid tenancy (HTTP API)
Hybrid tenancy combines physical and logical mappings in one Workflow Engine Web API host. Configure it by passing multiple WorkflowTenantCreationOptions entries to AddWorkflowTenants(). Each entry creates a physical tenant with its own runtime and provider, while its TenantIds array assigns one or more logical tenant IDs to that tenant:
// Physical: acme-corp has its own database and runtime// Logical: globex and stark share a database with TenantId filteringbuilder.Services.AddWorkflowTenants( new WorkflowTenantCreationOptions { TenantIds = ["acme-corp"], ConnectionString = "Server=db-acme;...", PersistenceProviderId = PersistenceProviderId.Mssql }, new WorkflowTenantCreationOptions { TenantIds = ["globex", "stark"], ConnectionString = "Server=db-shared;...", PersistenceProviderId = PersistenceProviderId.Mssql });Why it matters
Multitenancy delivers these outcomes:
- Lower infrastructure cost per customer - A single application server handles all tenants. You do not provision separate application infrastructure for each customer.
- Faster customer onboarding - Adding a new tenant means configuring a tenant identifier and a database connection string. Onboarding takes minutes instead of days.
- Centralized operations - One application to deploy and monitor, one set of upgrades to apply. Operations teams manage one system, not one per customer.
- Flexible isolation model - Choose physical isolation for separate databases, logical isolation for shared storage, or a hybrid model for different customer tiers in one API host.
- Data separation at the persistence level - Physical tenants can use separate databases. For logical tenants, Data API queries use the selected
TenantId, and RPC API operations validate the process tenant.
Who it is for
Evaluator (CEO, CTO, PM): Multitenancy is the infrastructure that lets you offer process automation as a SaaS product. It reduces per-customer cost, simplifies operations, and removes the architectural barrier to adding new clients. Choose physical tenancy for regulated industries that require database-level separation, or logical tenancy for internal multi-division deployments.
Developer: Configure one or more tenant identifiers for each runtime and data provider. In the HTTP API, use the Workflow-Api-Tenant-ID header to select a logical tenant. In the core runtime, set TenantId on CreateInstanceParams. Read processInstance.TenantId in actions and rules for tenant-specific behavior.
Enterprise architect: Physical tenancy gives a tenant its own WorkflowRuntime and IDataProvider. Logical tenancy maps multiple tenant IDs to one runtime and provider with TenantId filtering. Hybrid tenancy combines both mappings in the same API host.
When to use it
Use multitenancy when your business model requires data separation between customers or business units but you want operational efficiency from a shared deployment. Typical examples:
- SaaS process automation platform - You host approval workflows, document reviews, or compliance processes for multiple client organizations from a single application. Physical tenancy gives selected clients an independent database, while logical tenancy keeps other clients isolated in shared storage.
- Multi-division enterprise deployment - A single enterprise runs Workflow Engine for HR, finance, and operations. Each division has isolated data, and regulatory requirements demand data separation between divisions. Logical tenancy with
TenantIdfiltering is usually sufficient. - ISV embedding workflows - Your product ships with embedded workflow capabilities. Each of your customers runs their own workflows in isolation, but you manage one deployment rather than one per customer.
How it compares
There are four approaches to tenant separation. The table below shows the tradeoffs.
| Approach | What it requires | Result |
|---|---|---|
| Separate deployment per tenant | Provision, monitor, and maintain one full application and database per customer | High infrastructure cost, complex operations, slower onboarding |
| Workflow Engine logical tenancy | One WorkflowRuntime and provider serve multiple tenant IDs. | Lower cost, centralized management, tenant-aware data filtered by TenantId |
| Workflow Engine physical tenancy | One application deployment. Each tenant has its own database and WorkflowRuntime. | Lower infrastructure cost, full data isolation, per-tenant backup/restore |
| Workflow Engine hybrid tenancy | One API host maps some tenant IDs to dedicated runtimes and providers and groups other IDs on shared ones. | Different isolation levels for different customer or regulatory requirements |
The key tradeoff is operational complexity vs. isolation strength. Separate deployments give full independence (including per-tenant application versions) but add operational overhead. Logical tenancy shares everything except the TenantId filter. Physical tenancy shares the application but not the database. Hybrid tenancy applies either model per tenant group without adding another API host.
See also
Workflow Engine Editions
Which editions include multitenancy and what each edition provides.
Pluggable Security
How permissions and access control work across the Workflow Engine API.
Frequently asked questions
Does multitenancy require a specific license?
Yes. Multitenancy requires a Workflow Engine NEO license that enables the multitenancy feature. See Workflow Engine Editions for licensing details.
How does the API identify which tenant a request belongs to?
The HTTP API reads the Workflow-Api-Tenant-ID HTTP header on each request. The header value identifies a logical tenant, and the request snapshot maps it to the physical tenant's WorkflowRuntime and data provider. If no header is provided, the API uses DefaultTenantId; if neither value is available, the API returns an error.
Can a tenant access another tenant's processes if they know the process ID?
In physical tenancy, each tenant can use separate storage. In logical and hybrid tenancy, Data API operations filter by the selected tenant ID and RPC API operations validate the process tenant. A process from another tenant is returned as not found rather than exposed to the caller.
How does multitenancy affect backups and restores?
In the physical model, each tenant can have its own database, so you can back up and restore tenants independently. In the logical model, tenants share a database, so restore affects that tenant group. In the hybrid model, the database connection assigned to each physical tenant group determines the backup boundary.
What happens to running instances when I add a new tenant?
Adding a new tenant is a registry change. Register a new IWorkflowTenant, or create one from WorkflowTenantCreationOptions with one or more logical IDs. The registry publishes a new immutable snapshot for new requests; existing requests keep their previous snapshot until they complete.
How does TenantId propagate to subprocesses?
TenantId is a system parameter with MergeIntoParentProcessIsProhibited = true. It is carried forward when a subprocess is created from the parent, but when the subprocess merges back, the parent's TenantId is not overwritten. This ensures the tenant identity is preserved throughout the process tree.
Can I control which users can access which tenants?
Yes. The HTTP API includes a granular permission system. Use IWorkflowApiPermissions.BuildClaim(...) and IWorkflowApiPermissionsBuilder to configure tenant-level rules: AllowAllTenants(), DenyAllTenants(), AllowAllTenantsExcept(...), or DenyAllTenantsExcept(...). API authorization checks both operation and tenant permissions on every secured request.