Skip to content

Multi-tenancy and data isolation

Each customer organisation is a tenant. Tenants share the platform, but each one sees only its own data, and no request, event or delivery crosses from one tenant to another.

A request acts for the tenant its credentials belong to, and nothing else:

  • a user’s access token carries the user’s tenant, set when the token was issued;
  • an API key belongs to the tenant that created it.

No tenant-facing URL or request body carries a tenant ID, and there is no header a caller can send to choose a tenant. The gateway removes any identity information a caller supplies and passes on only the tenant, user and permissions it established from the credentials. A user belongs to one tenant.

Where each tenant has its own address (<tenant>.<domain>), the address is a guard, not a source of tenancy. Signing in at a tenant’s address works only for that tenant’s users. A sign-in at the main address moves to the tenant’s address with a single-use code that expires in a minute and travels in the part of the URL that is never sent to a server; no token ever appears in a URL. Certificates are issued only for the addresses of tenants that exist.

Tenants share each service’s database, and every record a tenant owns carries its tenant. Each service enforces isolation in its data layer: a filter on the current tenant is applied to its queries automatically, rather than left to each query to remember. Where the identity service must look past that filter, for example to check that an email address is free across jtWMS, it still limits every tenant-owned read and change to the caller’s tenant.

As a result, a request can’t read, change or even detect another tenant’s records. An ID that belongs to another tenant behaves exactly like an ID that doesn’t exist: the response is 404 Not Found. Uniqueness rules, such as a product’s SKU, apply within a tenant, so two tenants can use the same codes. The one exception is a user’s email address, which is unique across jtWMS: an address can belong to only one user, in one tenant.

The same isolation holds outside HTTP requests:

  • Every event records the tenant whose change it describes, and work done in response to an event runs in that tenant’s context, with the same data filters.
  • A webhook delivery goes only to the subscriptions of the tenant the event belongs to.
  • The audit trail is kept per tenant, and a tenant can read only its own entries.

Plans and features apply per tenant. A tenant’s plan, with any add-ons, sets:

  • Feature modules. Routes for a module the plan doesn’t include, such as the product catalog, are refused at the gateway with 403 feature_not_entitled.
  • Limits. The number of API keys the tenant can hold, and its daily API request quota.

Changing plan takes effect for users when their session next renews (an access token lasts at most 15 minutes by default) and for API keys within about a minute. See Rate limits and feature gates and Plan & Billing.

An organisation can create one sandbox: a separate tenant, linked to the organisation, kept apart from its real data. A sandbox is isolated exactly like any other tenant: nothing in it is visible from the organisation’s own tenant, and nothing from the organisation is visible inside it. It is on its own free plan, with the modules a first order and pick need and small limits, and it can’t invite people or change plan. Users enter it by switching their session from the organisation, never by signing in to it: each gets their own account inside the sandbox, so its activity is recorded per person, and a sandbox session ends as soon as the person’s access to the organisation does.

Resetting or deleting a sandbox retires its tenant for good: its users’ sessions end, its API keys stop working, and no credential can reach its data again. A reset starts a new, empty sandbox.

Within a tenant, what each user or API key can do is set by permissions, granted through roles to users and directly to API keys. See Security model.

The platform operator’s administrators manage plans, features and each tenant’s subscription through separate platform endpoints that tenants can’t use.