Skip to content

Tenants

Multi-tenancy lets several independent organisations share one Stalwart deployment, as a hosting provider does for its customers. Each organisation is a tenant. A tenant has its own domains, accounts, groups, mailing lists and other objects, and it is isolated from the other tenants in three ways:

  • Accounts of one tenant cannot reach the objects of another.
  • A tenant administrator manages only the tenant’s own objects.
  • The server operator decides how many resources and which permissions each tenant receives.

Each tenant is a Tenant object (found in the WebUI under Management › Directory › Tenants). The object holds a name, its permissions and its quotas. It can also hold a logo, which brands the WebUI for the tenant’s users (Branding).

An object belongs to a tenant through its memberTenantId field. The following objects can belong to a tenant:

How memberTenantId is set depends on who creates the object. Objects that a tenant administrator creates are placed in the administrator’s tenant automatically. The server operator, who works outside any tenant, sets memberTenantId explicitly.

A tenant administrator is an account of the tenant whose roles is Admin. For an account inside a tenant, Admin applies the Authentication singleton’s defaultTenantRoleIds instead of the server administrator roles. By default these are the Tenant Administrator and User roles. They allow the account to manage the tenant’s domains, accounts, groups, mailing lists, roles, OAuth clients, DKIM signatures, ACME providers, DNS servers and queued messages, and nothing outside the tenant.

A tenant sets the most that its members may hold, through its own roles and permissions. The server computes the effective permissions of a member from the member’s own roles and permissions, and then restricts the result to those of the tenant (Permissions). A permission that the tenant lacks therefore has no effect on its members, whoever assigns it.

The ceiling is chosen in the same way as an account’s permissions. With roles set to Default, it is the roles in defaultTenantRoleIds. Custom selects other roles. permissions then adjusts the result with the Inherit, Merge and Replace modes.

Account quotas limit each member on its own. A tenant’s quotas map adds a second limit, on what the tenant may consume in total:

QuotaLimit
maxDiskQuotaDisk space used by all members together, in bytes
maxAccounts, maxGroupsUser accounts and group accounts
maxDomains, maxMailingLists, maxRolesDomains, mailing lists and roles
maxOauthClientsRegistered OAuth clients
maxDkimKeys, maxAcmeProviders, maxDnsServers, maxDirectoriesDKIM keys, ACME providers, DNS servers and external directories

The disk quota is shared among the members. Suppose a tenant has a 100 GB quota, and one member uses 60 GB and another 40 GB. No member can then store more until usage falls, whatever its own account quota allows. An IMAP client that hits the limit receives NO [OVERQUOTA] Organization disk quota exceeded., and mail for members is deferred with Organization over quota. (Quotas).

The object quotas apply to every object created for the tenant, whether a tenant administrator or a server administrator creates it. They also apply to an existing object that is moved into the tenant by changing its memberTenantId. A creation beyond the limit fails with the JMAP error overQuota and a description such as You have exceeded your quota of 50 accounts.

Tenant administrators are not trusted with the server’s network position. An object configured by a tenant could otherwise make the server contact internal services or read local files on the tenant’s behalf. Objects owned by a tenant are therefore subject to restrictions that do not apply to the server’s own objects:

  • URLs configured on tenant-owned objects, such as DNS server endpoints, ACME directories and domain logos, must use https, must not contain credentials and must resolve to public IP addresses.
  • Secrets of tenant-owned objects must be given as values. The File and EnvironmentVariable sources, which would read from the server’s file system or environment, are rejected.
  • OAuth clients owned by a tenant are shown as unverified on the consent screen, and they sign in only accounts of that tenant. Any other account receives access_denied (OAuth clients).
  • An OpenID Connect directory owned by a tenant contacts its identity provider only on public IP addresses (OpenID Connect directory).