feat(keycloak): organizations become the membership authority source
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
This commit is contained in:
co-authored by
Claude Fable 5
parent
4eaee521d4
commit
3405579891
@@ -75,11 +75,12 @@ type Adapter interface {
|
||||
SyncClaims(ctx context.Context, userID string, c Claims) error
|
||||
|
||||
// Memberships resolves the tenants user userID (the Keycloak user id,
|
||||
// i.e. the JWT `sub`) belongs to, as Keycloak records them. The realm
|
||||
// has no Organizations yet, so this reads the user's attribute
|
||||
// projection — zero or one memberships. When the realm migrates to
|
||||
// Organizations this becomes an org-membership query and callers keep
|
||||
// working unchanged. Returns ErrUserNotFound for an unknown user id.
|
||||
// i.e. the JWT `sub`) belongs to, as Keycloak records them. Since the
|
||||
// realm enabled Organizations (2026-09-01) this is an org-membership
|
||||
// query: one membership per enabled org the user belongs to (alias =
|
||||
// tenant slug, org attribute tenant_id = registry UUID). The legacy
|
||||
// user-attribute projection no longer grants membership on its own.
|
||||
// Returns ErrUserNotFound for an unknown user id.
|
||||
Memberships(ctx context.Context, userID string) ([]Claims, error)
|
||||
|
||||
// Health pings the admin endpoint. Used by readyz and the cluster cold-
|
||||
|
||||
Reference in New Issue
Block a user