Skip to content

Deferred: Keycloak/JWT extension of access control

Deferred Keycloak/JWT hybrid extension of vxData access control — design, parked PRs, and the order to reopen them.

v1 runs on static tokens only (API_PRINCIPALS). The Keycloak path was built, tested, and deliberately parked (2026-07-14) as closed draft PRs with branches kept — extending is “reopen + rebase”, not redesign.

Design (already validated)

The resolver in api/auth.py accepts one credential kind today. The hybrid was: same Authorization: Bearer header; a credential with two dots is verified as a Keycloak JWT (PyJWT + cached JWKS, RS256, iss/aud=vxdata-api/exp), then claims map to the same Policy: groups claim via group_grants, azp via client_grants. Unknown claims = empty policy (authenticated, reads nothing). Config lives in an optional oidc block inside API_PRINCIPALS:

{"tokens": {...}, "oidc": {"issuer": ".../realms/virdx", "audience": "vxdata-api",
 "group_grants": {"vxdata-admins": [...], "vxdata-users": [...]},
 "client_grants": {"some-bot": [...]}}}

Keycloak stays pure authentication; permissions never leave vxData config.

The parked pieces (reopen in this order)

  1. API resolver — mono PR #236 (branch feat/vxdata-oidc-resolver): JWT verification + claims mapping + per-request principal logging; fake-JWKS test matrix (expired/wrong-aud/wrong-iss/tampered). Dormant without the oidc block, so it can merge any time.
  2. Realm clients — infra_ansible PR #75 (felix/vxdata-keycloak-clients): vxdata-cli public client with device grant, vxdata-api audience-only client, audience mappers on dashboard/vxdata-cli, template attributes passthrough. Applies on Keycloak restart; coordinate with anything touching the dashboard client (e.g. old #59).
  3. Groups — infra_iam PR #28: vxdata-admins (felix, moritz) / vxdata-users (eng roster). Propagates via auth-sync -> FreeIPA -> LDAP mapper (~5 min; tokens pick groups up on next login).
  4. Human CLI login — mono #237’s dropped commit (vxdata login, device grant, token cache/refresh in ~/.config/vxdata/, transport fallback): recover from the #237 branch history.
  5. Dashboard PKCE — mono PR #238 (feat/dashboard-keycloak-login): oidc-spa + fetch-wrapper bearer + dashboard-api user-token forwarding. Known issue to fix on reopen: VITE_OIDC_ISSUER is baked at build time but one image serves staging+prod — needs runtime injection (the window.__APP_BASE__ pattern). Also add the staging redirect URI in #75.

Until then

Humans and bots use static tokens (VXDATA_TOKEN); audit granularity is the token subject. When enforcement reaches the dashboard: reopen #238, or interim edge-injected static token (identity collapses to “dashboard”).

Navigation

Type to search…

↑↓ navigate↵ selectEsc close