Gatekeeper is multi-tenant. Every customer workspace is an isolated tenant, and almost every resource - API keys, usage events, roles, webhooks, audit entries - belongs to exactly one tenant. Isolation is not a convention checked in route code. It is enforced inside the one decision engine, so a route cannot accidentally skip it.
Tenants and memberships#
A tenant is an isolated customer workspace. A membership links a user to a tenant and carries a role. Tenant-scoped routes pass the tenant id to the guard; the engine's membership step then verifies the actor actually belongs to that tenant before any tenant resource is reachable.
Roles are ordered by capability:
| Role | Can manage members and settings | Notes |
|---|---|---|
owner | yes | Highest. Only an owner may define or grant the *:* wildcard or the owner role itself. |
admin | yes | Manages members and most tenant resources. |
member | no | Ordinary access; cannot manage other members. |
The role returned on a successful decision (tenantRole) drives finer permission checks. Roles bundle permissions; a permission is the granular capability checked individually (for example a tenantManage or permission policy in the pipeline).
The five actor kinds#
A credential is the raw, unverified proof a caller presents. An actor is the verified principal it resolves to. The identity step turns one into the other, and the engine recognises exactly five actor kinds. Anything unwired resolves as invalid (fail closed).
| Credential | Resolves to actor | Used on |
|---|---|---|
bearer (user JWT) | user - carries a userId | tenant routes |
apiKey (orka_live_...) | apiKey - tenant-bound and scoped | key validate / token |
platformKey (gkp_...) | platform - a service account with permissions | platform / control-plane routes |
platformBootstrap (boot token) | platformBootstrap | platform management only |
none | anonymous | public / pre-auth routes |
Anonymous passing identity is intentional. A route that genuinely permits anonymous traffic can be expressed without special-casing, while a route guarded by, say, a self-or-manage policy still rejects anonymous in the authorization step with UNAUTHENTICATED.
Platform actors#
A platform actor is a non-user principal used for control-plane operations. There are two: a service account (platform, authenticated by a platformKey) and the bootstrap principal (platformBootstrap, authenticated by a break-glass boot token). The bootstrap token is a superuser accepted only on service-account management routes. Operational platform routes set a "require service account" flag, which denies the bootstrap token outright.
Edge-enforced isolation#
Three controls keep tenants apart, all evaluated before any tenant resource is touched:
- Membership check. The authorization step rejects a
useractor who is not a member of the requested tenant withNOT_A_MEMBER(403). - Cross-tenant binding guard. An
apiKeyactor is bound to exactly one tenant. Pointing it at a different tenant is denied before any role lookup - the binding step halts first. - Existence hiding. A route can opt into hiding existence: when set, the guard remaps the
403 NOT_A_MEMBERto404, so a non-member cannot distinguish "exists but forbidden" from "does not exist."
Related#
- Architecture - the decision engine and pipeline order
- Responses and errors - how
403/404surface to clients - Rate limits - per-credential and per-key throttling