feat(keycloak): organizations become the membership authority source #19

Merged
sharang merged 1 commits from feat/rbac-orgs-membership into main 2026-09-01 09:03:24 +00:00
Owner

Prod-shape membership: the breakpilot-dev realm now has Organizations enabled, and Memberships switches from the user-attribute projection to the org-membership query (GET /organizations/members/{id}/organizations).

  • One membership per ENABLED org: alias = tenant slug, org attribute tenant_id = registry UUID (exactly what CreateOrgAndInvite already writes)
  • Per-user claim attrs (org_roles/products/plan/tenant_status) still come from the user record (SyncClaims maintains them)
  • ErrUserNotFound preserved via the existing user lookup
  • Pinned behavior change: legacy tenant attributes alone grant NO membership (revocation via org removal is immediate and cannot be undone by stale attributes)

Realm groundwork already applied on breakpilot-dev: organizationsEnabled=true, org acme (alias acme, tenant_id attr = registry UUID) with test user membered, organization scope now a default scope on compliance-client / dev-portal / matrix-tester, verified token carries organization:["acme"].

Local: gofmt/vet clean, full suite green with -race, coverage 71.1% (gate 70).

Prod-shape membership: the breakpilot-dev realm now has Organizations enabled, and Memberships switches from the user-attribute projection to the org-membership query (GET /organizations/members/{id}/organizations). - One membership per ENABLED org: alias = tenant slug, org attribute tenant_id = registry UUID (exactly what CreateOrgAndInvite already writes) - Per-user claim attrs (org_roles/products/plan/tenant_status) still come from the user record (SyncClaims maintains them) - ErrUserNotFound preserved via the existing user lookup - Pinned behavior change: legacy tenant attributes alone grant NO membership (revocation via org removal is immediate and cannot be undone by stale attributes) Realm groundwork already applied on breakpilot-dev: organizationsEnabled=true, org acme (alias acme, tenant_id attr = registry UUID) with test user membered, organization scope now a default scope on compliance-client / dev-portal / matrix-tester, verified token carries organization:["acme"]. Local: gofmt/vet clean, full suite green with -race, coverage 71.1% (gate 70).
sharang added 1 commit 2026-09-01 07:39:21 +00:00
feat(keycloak): organizations become the membership authority source
ci / shared (pull_request) Successful in 13s
ci / test (pull_request) Successful in 21m19s
ci / image (pull_request) Skipped
3405579891
The realm enabled Keycloak Organizations (prod shape): Memberships now
queries GET /organizations/members/{id}/organizations and emits one
claim per enabled org — alias = tenant slug, org attribute tenant_id =
registry UUID (both already written by CreateOrgAndInvite). Per-user
claim attributes (org_roles/products/plan/tenant_status) still ride
along from the user record, and ErrUserNotFound semantics are kept.

Deliberate behavior change, pinned by test: the legacy user-attribute
tenant projection no longer grants membership on its own, so a stale
tenant_id attribute cannot resurrect access an org removal revoked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CNdLL9BdsWm7MCyui5ffPD
sharang merged commit 84516e9b4f into main 2026-09-01 09:03:24 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: platform/tenant-registry#19