Org-Aware Tokens & Sessions
Summary
Keymate's generic organization-context design selects one eligible membership context for a requesting authenticated client session and projects a minimal, versioned org_context claim into that client's tokens. The claim identifies the selected context; it does not copy the user's complete effective-role or permission inventory into the token.
Why It Exists
A user can hold multiple independent memberships, sometimes across multiple Tenants and organizations. Authentication proves who the user is, but a requesting application still needs an explicit, application-eligible context for organization-scoped work. Central selection keeps the eligibility decision server-side and prevents clients from activating arbitrary membership or hierarchy identifiers.
Where It Fits in Keymate
The Membership & Application Assignment model owns memberships. KEOPS combines active effective memberships, the requesting client's Keymate Application binding, Application Availability, and active hierarchy state to compute eligible contexts. The organization-context runtime writes the selected canonical context to the requesting Keycloak authenticated client session and projects it into tokens.
Role and permission evaluation remains an authorization concern. A context identifier can be used to resolve current facts, but the org_context claim is not itself a durable role store.
Contract Boundaries
- Domain providers own truth. Membership, application, tenant, and organization providers own their data and validation.
- KEOPS owns cross-domain eligibility. Unknown clients, stale memberships, unavailable applications, ambiguous bindings, and inconsistent hierarchy data fail closed.
- The authenticated client session owns selection. Context is not a single mutable value on the root SSO user session.
- The token carries a minimal reference. The versioned
org_contextclaim contains canonical context identifiers, not a full permission inventory. - Authorization resolves effective access. Services use the selected context with the applicable authorization profile instead of treating a stale token role list as current domain truth.
How It Works
1. Compute Eligible Contexts
The server resolves the requesting native client to one active Keymate Application and intersects:
active effective memberships
∩ application availability
∩ active tenant and organization hierarchy
= eligible organization contexts
The server considers a stored default only after computing this set. A default never grants eligibility.
2. Select and Revalidate
Zero eligible contexts fail closed. One can be selected automatically. With multiple contexts, the selector renders only server-filtered choices. A submitted choice is evaluated again so a stale or manipulated browser value cannot activate a context.
3. Bind the Requesting Client Session
The canonical selection is stored on the requesting AuthenticatedClientSessionModel. Two applications sharing one root SSO session can therefore hold different organization contexts without overwriting each other.
4. Issue a Fresh Token Set
The runtime issues a fresh token set for the requesting client with a versioned org_context claim. The contract includes the identifiers needed to name the canonical selected context and excludes a potentially stale complete role or permission list.
The runtime contract delivered with KEOPS #307 governs the exact fields and claim version. Consumers must reject unsupported versions and must not infer fields that are absent.
Browser and BFF Switching Profiles
Browser Authorization Code + PKCE
A public browser client re-enters the same-realm authorization-code flow with PKCE. The server recomputes eligibility, performs selection or confirmation, updates that client's session, and returns a fresh authorization code and token set. A public client is not required to hold a client secret or invoke a privileged token exchange.
Confidential Client or BFF Exchange
An approved confidential client can use the planned organization-context exchange. The server authenticates and authorizes the client, validates subject/audience/session constraints, recomputes eligibility, updates only that client session, and returns a fresh token response. The BFF must atomically replace server-side access and refresh token state and rotate its own HttpOnly application-session cookie.
Token and Durable-Fact Lifecycles
These lifecycles are related, but they are not the same operation:
| Lifecycle | What changes | What is not implied |
|---|---|---|
| Membership disable/removal | The exact membership becomes ineligible; the planned lifecycle cascade removes role assignments anchored to it | Other active memberships are not deleted |
| Role-assignment cleanup | Durable direct and template-sourced role facts for that membership are removed | Previously issued self-contained access tokens are not rewritten |
| Context switch | The requesting client session receives a new selected context and fresh token set | Sibling client sessions are not changed |
| Refresh rotation | The client replaces its refresh capability according to the runtime profile | An earlier access token is not automatically revoked |
| Access-token expiry/revocation | The token becomes unusable according to expiry and the configured enforcement profile | Durable cleanup alone does not prove immediate invalidation |
An already issued self-contained access token can remain cryptographically valid until expiry unless the selected profile adds and enforces revocation, introspection, or another current-state check. Applications must follow their deployment's token validation profile rather than assuming that context switching or membership cleanup invalidates an old token immediately.
Diagram
Example Scenario
Scenario
Jane holds active memberships in organizations A and B for the same application. Her browser client currently uses A.
Input
- Actor: Jane, authenticated through a public browser client
- Resource: Organization-scoped application access
- Action: Change the requesting client from organization A to organization B
- Context: Both memberships remain active and eligible for the application
Expected Outcome
- Jane selects B and re-enters the authorization-code + PKCE flow.
- The server recomputes eligibility and confirms that B remains eligible.
- Only that browser client's authenticated client session is updated.
- The client receives and stores a fresh token set containing B's minimal context reference.
- Membership B remains active. Membership A also remains active unless an explicit membership lifecycle command disables or removes it.
If an administrator separately removes membership A, the planned lifecycle cascade removes durable role assignments anchored to A. That cleanup does not delete B, change a sibling application's selected context, or by itself guarantee immediate rejection of an already issued A access token.
Common Misunderstandings
- "One root SSO session has one global organization context." Each requesting authenticated client session owns its context; sibling clients can differ.
- "The token contains all effective roles." The accepted generic contract keeps
org_contextminimal and versioned. Authorization can resolve current role facts separately. - "Switching context immediately revokes the old access token." A new token set replaces client-held state, but automatic invalidation of an already issued access token requires an explicitly enforced token policy.
- "Selecting B deletes membership A." Context selection is not membership replacement. Multiple memberships are supported.
- "Removing a membership and invalidating tokens are one transaction." Durable membership/role cleanup and issued-token lifecycle are distinct guarantees.
Design Notes / Best Practices
- Keep organization context scoped to the requesting authenticated client session.
- Recompute membership and application eligibility whenever the client selects or refreshes a context.
- Keep the token claim minimal and resolve current authorization facts at the enforcement boundary.
- Treat membership cleanup, context replacement, and issued-token invalidation as separate controls with explicit operational policies.
Use short access-token lifetimes or a supported current-state enforcement mechanism when the application requires stale organization access to stop before token expiry.
Related Use Cases
- A user selects among multiple active organization memberships for one application.
- Two applications maintain different organization contexts under one root SSO session.
- An administrator disables one membership without affecting another active membership.
- An authorization service rejects a stale context after membership state changes.
Delivery Status
| Capability | Status |
|---|---|
| Multiple independent membership records | Current product model |
| Canonical cross-domain context eligibility | Planned — KEOPS #306 |
| Generic client-session-scoped selector and minimal claim | Planned — KEOPS #307 |
| Confidential/BFF exchange and explicit rotation policy | Planned — KEOPS #308 |
| Exact-membership role cleanup on disable/removal | Planned — KEOPS #320 |
| Shared membership eligibility for direct, bulk, and template role assignment | Planned — KEOPS #321 |