feat(auth): resolve SSO users to a per-org tenant via the Bunyip org claim (PMS-240) #175
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/mapps-240-bunyip-org-tenant"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
Implements PMS-240: resolve each SSO user to their own org tenant instead of funnelling everyone into the shared default tenant (the root cause behind PMS-239).
Design (the agreed contract)
tenants.bunyip_org_idcolumn with a partial unique index (legacy tenants stay NULL; each org maps to exactly one tenant).TenantService::ensure_tenant_for_bunyip_orgis select-or-provision: inserts anorg-kind tenantON CONFLICT (bunyip_org_id) DO NOTHING(concurrent first-logins converge on one tenant - the race loser re-reads the winner), initialises ticket/invoice sequences, and runscopy_default_configso statuses/priorities/queues/SLA + notification templates exist out of the box. The SSO user is JIT-mirrored into the resolved tenant.Forward-compatible and inert until Bunyip ships the claim
AtClaims.bunyip_org_idis#[serde(default)], so current tokens deserialize it toNoneand keep falling back todefault_bunyip_tenant_id()- byte-for-byte the pre-PMS-240 behaviour. The tenant service is threaded intoAuthMiddlewareviawith_tenants; when the claim or the service is absent, the default-tenant fallback runs. A failed org→tenant resolution drops the bunyip path rather than landing the user in the wrong tenant.Security
The claim rides the already-verified Bunyip at+jwt (iss/aud/signature checked by
BunyipVerifier), so it is as authoritative assub/bunyip_role.Out of scope (follow-ups)
bunyip_org_id(cross-system; this PR is the consuming half).Org <id>+ a uuid-derived slug, renamable later).Verification
cargo check --all-targets,cargo clippy --all-targets: clean.tests/tenants.rs: newensure_tenant_for_bunyip_org_provisions_then_is_idempotent(provision -> same-org idempotent -> distinct-org distinct -> default config copied). Full tenants suite (6) and auth suite (14) green.034_tenant_bunyip_org.sqlis additive (nullable column + partial unique index).🤖 Generated with Claude Code