Skip to content

Multi-tenancy

One Drupal instance can host several isolated workflow realms, called tenants. Each tenant runs its own processes: instances, tokens and variables partition per tenant, so a query, a listing or a purge in one tenant never reaches another's rows.

Every install starts with one tenant out of the box, the default tenant, and that is all a single-tenant site ever needs. Multi-tenancy stays invisible until you create a second tenant, so a single-tenant site behaves as if tenancy were absent.

How isolation works

Each partitioned row records the tenant it belongs to in a tenant field. The value is stamped at create time by the engine, from the active tenant, and defaults to the default tenant so a row is never tenantless. A process workflow is either shared across every tenant (the default) or scoped to a single tenant.

Resolving the active tenant

Which tenant a request acts in is decided by tenant resolvers: services tagged orchestra.tenant_resolver implementing TenantResolverInterface. Each resolver returns a tenant machine name or NULL to defer; the first non-null answer wins, and if none answer the default tenant is used. With no resolver installed every request resolves to the default tenant.

To resolve tenants your own way, implement the interface and tag the service:

services:
  my_module.tenant_resolver:
    class: Drupal\my_module\MyTenantResolver
    tags:
      - { name: orchestra.tenant_resolver }

Mapping a domain to a tenant

The optional orchestra_domain submodule maps the active domain (from the Domain module) to a tenant, so each domain runs its own isolated set of processes on one Drupal instance. Bind a domain to a tenant on the domain add/edit form (the binding is a third-party setting on the domain record); a request served on that domain then acts in the bound tenant, falling back to the default when a domain has no binding. It is just another tenant resolver, so the kernel itself stays domain-agnostic.

Tenant-scoped operators

The process instances UI (provided by orchestra_ui) lives under Structure at /admin/structure/orchestra/instances, with a menu link and a canonical link template per instance. Two permissions gate it:

  • Access Orchestra process instances (access orchestra instances): a tenant-scoped operator who sees and drives only their own tenant's instances. The list and the per-instance page resolve the active tenant the usual way and show only that tenant's rows.
  • Administer Orchestra (administer orchestra): the cross-tenant super-permission. A holder reaches every tenant's instances and is not narrowed to the active one.

So you can give an operator day-to-day control of one realm's processes without handing them the keys to every other tenant on the site.