Phase 2b: Keycloak Auth + Tenant Scoping

phase-minio-mobile-2b-keycloak-auth Phase

phase
Goal: Add Keycloak OIDC token validation and tenant-scoped access control to the FastAPI service — stakeholders see only their prefix, admins see everything.
Owner: Dev agent
Repo: forgejo_admin/minio-api
Depends on: phase-minio-mobile-2a-fastapi-routes (API routes must exist first)

Scope

  • Keycloak OIDC token validation middleware — every request must have valid Bearer token
  • Decode JWT, validate signature against Keycloak's JWKS endpoint
  • Extract role and group claims from token
  • Tenant scoping: Keycloak group claims map to MinIO bucket prefixes (e.g., group westside → prefix assets/westside/)
  • Admin role bypasses scoping — sees all buckets and prefixes
  • Stakeholder role: list/get/upload scoped to their prefix, no delete, no other buckets
  • 401 on missing/invalid token, 403 on out-of-scope access
  • Tests: mock Keycloak tokens for unit tests, real Keycloak for integration tests

Auth Model

Role Buckets Prefix Operations
admin All All Full CRUD
stakeholder assets only Scoped to group claim (e.g., <code>westside/</code>) List, Get, Upload — no Delete

Deliverables

  • PR #5 merged (squash) — 2026-03-22
  • auth.py — JWKS caching + JWT validation via PyJWT, TokenUser dataclass
  • permissions.py — tenant scoping: group claim → prefix, admin bypass, stakeholder restrictions
  • Auth injected on all 15 endpoints via FastAPI Depends(get_current_user)
  • 401 on missing/invalid/expired token, 403 on out-of-scope access
  • AUTH_DISABLED=true for local dev — existing integration tests unaffected
  • 63 new tests (15 auth unit, 28 permissions unit, 20 middleware HTTP-level) — all passing
  • phase-minio-mobile-2-api-auth — parent phase
  • phase-minio-mobile-2a-fastapi-routes — prerequisite (API routes)
  • phase-minio-mobile-2c-k8s-deploy — next subphase (deploy)