Skip to content

ADR-063: Namespace grant list authorization for clients

Category: architecture Provenance: guided-ai

Decision

Replace dual-token authorization model with declarative namespace grant list approach. Realm creation is unrestricted (controlled only by Kubernetes RBAC). Client creation requires explicit namespace authorization via clientAuthorizationGrants list in realm spec. No user-facing tokens required - authorization is purely declarative and GitOps-native.

Rationale

The dual-token authorization model created complexity and deviated from GitOps principles: Problems with token-based auth: - Complexity: Token generation, distribution, rotation lifecycle - Manual intervention: Platform team distributing secrets - Cross-namespace coordination: Secret syncing between namespaces - Not GitOps-native: Secrets don't belong in Git, rotation causes drift - Team churn: Long-lived credentials outlive team membership Benefits of grant list approach: - Simplicity: No token management at all for users - GitOps-native: Authorization as declarative list in realm manifest - PR workflow: Access control through standard code review - Clear ownership: Realm team explicitly controls client access - Audit trail: Git history shows all access changes - Self-service: Teams create realms without platform intervention - Kubernetes-native: Follows RBAC patterns, integrates with existing security model Capacity management addresses operational scaling: - Operators can set maxRealms limit to prevent resource exhaustion - allowNewRealms flag enables graceful capacity handling - Existing realms continue working when capacity reached - Clear messaging guides users to alternative operators Trade-offs: - Realm teams maintain grant lists (added overhead) - Requires cross-namespace read permissions for operator - Revocation only blocks new clients, existing continue (by design) This aligns with ADR 003 (least privilege), ADR 004 (GitOps-first), ADR 005 (no plaintext secrets), ADR 016 (multi-namespace), and ADR 017 (K8s RBAC over Keycloak security).

Agent Instructions

When implementing client reconciliation, always fetch the referenced realm CR and validate that the client's namespace is present in spec.clientAuthorizationGrants. Reject client creation/update if namespace not in grant list. For realm reconciliation, validate capacity limits before creating new realms. Never implement user-facing token generation, distribution, or validation - all authorization is through grant lists. Status fields must reflect current authorization state (authorizedClientNamespaces in realm, authorizationStatus in client).

Rejected Alternatives

Keep dual-token model with improvements

Still requires secret distribution and management. Doesn't solve fundamental GitOps incompatibility. Complexity remains even with better tooling.

Use admission webhooks for validation

Adds infrastructure complexity. Grant list in CRD is simpler and equally effective. Webhooks better suited for more complex validation logic we don't need here.

Per-namespace operators instead of grant lists

Doesn't enable cross-namespace client provisioning. Requires multiple operator deployments. Goes against ADR 016 (multi-namespace by default).

Keycloak's built-in authorization

Conflicts with ADR 017 (K8s RBAC over Keycloak security). Creates dual authentication layer. Not GitOps compatible. Operator would need Keycloak admin credentials.