ADR 0001: Single active tenant (agency_id) per access token
Status
Accepted (design phase)
Context
The platform is multi-tenant: many agencies share one deployment. Users may have multiple memberships (e.g. a lead with the same mobile under agency A and agency B; or a partner who works for one agency only, but the same pattern applies).
Access tokens must tell the API which tenant context applies to each request so that queries can enforce agency_id scoping without ambiguity.
Alternatives:
- Single active tenant per access token — Each JWT contains exactly one
agency_id(and relatedmembership_id,lead_idorpartner_id). - Multi-tenant claims — One JWT lists all agencies the user may access; the client sends a header to pick the active one.
- No tenant in token — Resolve tenant only from hostname/header every time;
subalone is insufficient for row-level checks.
Decision
Use option 1: each access token encodes one active agency_id and the membership relevant to that agency (see auth-and-multitenancy.md §7).
To act in another agency context, the client calls a switch context (or re-login) flow and receives new access (and refresh) tokens.
Consequences
Positive
- Authorization logic stays simple:
request.agency_id == token.agency_idfor tenant-scoped endpoints. - Fewer mistakes than inferring tenant from optional headers alone.
- Aligns with “one session, one workspace” mental model.
Negative
- Switching agency requires a round-trip to obtain new tokens (acceptable for web and mobile).
- Refresh token strategy must define whether refresh is bound to one tenant or can rotate context (recommend: issue tenant-scoped refresh or re-auth for context switch).
Compliance
This ADR does not block future optional listing of “available memberships” in a separate unprivileged endpoint for UX; it only restricts what the bearer token may access in one hop.