Skip to main content

Multi-Tenancy

O2ID is multi-tenant: one instance hosts many isolated tenants, each its own identity universe — its own users, applications, roles, resource servers, and OIDC issuer. Tenants share nothing; a user in one tenant is invisible to every other.

Tenant-scoped URLs

Every endpoint is served under a tenant path prefix: /t/{tenant}/…, where {tenant} is the tenant's slug. For example, the OpenID discovery document for the acme tenant is at:

GET /t/acme/.well-known/openid-configuration

and it reports a per-tenant issuer:

{
"issuer": "https://id.example.com/t/acme",
"authorization_endpoint": "https://id.example.com/t/acme/oauth2/authorize",
"token_endpoint": "https://id.example.com/t/acme/oauth2/token"
}

The health check (/health) and the portal's static assets (/portal/static/…) are the only global, un-prefixed paths.

The system tenant

On first run, o2id serve seeds a tenant named system and creates the platform admin inside it. The system tenant holds platform-level identities — the operators who manage the deployment itself. o2idctl targets system by default.

Tenant-scoped identities

A user belongs to exactly one tenant. There is no cross-tenant membership: an operator who administers several tenants has a separate account in each. Email uniqueness is per-tenant, so alice@example.com can exist independently in two different tenants.

Platform vs tenant administration

Two distinct levels of authority:

  • Platform admin — holds the platform scope namespace (tenants:*) and can create and manage tenants across the deployment. Seeded into the system tenant on first run.
  • Tenant admin — holds * (every scope) within a single tenant. Can fully administer that tenant's users, apps, and roles, but has no cross-tenant authority.

Crucially, a tenant's * wildcard does not include the platform tenants:* scopes — so being a tenant admin never confers the ability to touch other tenants. Platform authority is granted explicitly, only by an existing platform operator.

Current status

Tenant provisioning (a tenants create|list|delete API and CLI, with per-tenant admin seeding on create) is not yet available — the system tenant is created automatically at startup. Each tenant also currently shares one OIDC signing key; per-tenant keys are planned. Until per-tenant keys land, treat OIDC ID-token verification across tenants as not yet isolated; access tokens are opaque and fully tenant-scoped.