RBAC Phase 1: membership authority endpoint + fail-closed API auth (#14)
Implements the model-B2 membership authority (ratified compliance auth design) and inbound token verification.
- GET /v1/users/{id}/memberships: Keycloak supplies user->tenant links + org_roles (attribute projection until the realm migrates to Organizations); registered tenants override status/plan/products from registry tables (source: registry|keycloak). Closes the M5.2-deferred org_roles stub.
- New internal/authn: OIDC discovery + JWKS verification (go-oidc/v3), audience tenant-registry. /healthz + /readyz stay PUBLIC_EXPLICIT; all other routes INTERNAL_SERVICE_ONLY. AUTH_ENABLED=true refuses to start on incomplete config (fail-closed); false (dev default) keeps current behavior.
- Full suite green incl. postgres testcontainers; openapi.yaml updated (contract test passes).
Activation is a separate step (Auth-5): requires the orca-infra env merge and a portal service token (portal currently calls with no auth).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Sharang Parnerkar <30073382+mighty840@users.noreply.github.com>
Reviewed-on: #14
This commit was merged in pull request #14.
This commit is contained in:
@@ -20,6 +20,13 @@ type Config struct {
|
||||
KeycloakClientID string
|
||||
KeycloakClientSecret string
|
||||
KeycloakTimeout time.Duration
|
||||
|
||||
// Inbound API auth (RBAC Phase 1). With AuthEnabled the server refuses
|
||||
// to start unless OIDC discovery against KeycloakIssuer succeeds, and
|
||||
// every non-health route requires a bearer token whose audience
|
||||
// contains AuthAudience.
|
||||
AuthEnabled bool
|
||||
AuthAudience string
|
||||
}
|
||||
|
||||
func Load() (*Config, error) {
|
||||
@@ -39,6 +46,9 @@ func Load() (*Config, error) {
|
||||
KeycloakClientID: os.Getenv("KEYCLOAK_CLIENT_ID"),
|
||||
KeycloakClientSecret: os.Getenv("KEYCLOAK_CLIENT_SECRET"),
|
||||
KeycloakTimeout: 10 * time.Second,
|
||||
|
||||
AuthEnabled: getenv("AUTH_ENABLED", "false") == "true",
|
||||
AuthAudience: getenv("AUTH_EXPECTED_AUDIENCE", "tenant-registry"),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user