Problem Statement. Today the backend uses static short-lived API keys via the
x-api-key header (api-key.guard.ts). The frontend has no documented way to obtain
short-lived tokens for the user session — everything is "service-to-service." A human user
of the dashboard cannot fully exercise the role hierarchy without resorting to a pre-issued
key.
Why it matters. Without short-lived tokens for users, audit trails collapse into
"which service did this" rather than "which human did this," undermining the JWT-auth
scheme already documented in the OpenAPI.
Technical Context. The Swagger config already declares 'JWT-auth'; the codebase
doesn't actually emit or verify JWTs.
Expected Outcome. Add a Keycloak-friendly OIDC layer: a TokenController
implements /oauth/token, /oauth/userinfo, /oauth/introspect, and /oauth/revoke.
JWTs are signed with an RS256 keypair loaded from env; users and API keys share one
principal model with role claims.
Acceptance Criteria.
- A new module
src/auth-oidc/ provides issuance/verification.
- Existing
ApiKeyGuard continues to accept x-api-key; new routes use @UseGuards(JwtAuthGuard).
- A revocation list (Redis sorted set keyed by
jti) prevents reuse of revoked tokens.
- E2E test verifies issue / refresh / revoke / introspect flow.
Implementation Notes. Use jose (low dep) and the existing Redis module rather
than rolling key management.
Files or modules likely to be affected. src/auth-oidc/* (new), src/auth/*,
src/common/guards/jwt-auth.guard.ts (new), app.module.ts.
Dependencies. #4 (same Redis), #12 (revocation list).
Difficulty. Hard
Estimated effort. L
Backlog item #10 from `docs/maintainer-issue-backlog.md.
Problem Statement. Today the backend uses static short-lived API keys via the
x-api-keyheader (api-key.guard.ts). The frontend has no documented way to obtainshort-lived tokens for the user session — everything is "service-to-service." A human user
of the dashboard cannot fully exercise the role hierarchy without resorting to a pre-issued
key.
Why it matters. Without short-lived tokens for users, audit trails collapse into
"which service did this" rather than "which human did this," undermining the JWT-auth
scheme already documented in the OpenAPI.
Technical Context. The Swagger config already declares
'JWT-auth'; the codebasedoesn't actually emit or verify JWTs.
Expected Outcome. Add a Keycloak-friendly OIDC layer: a
TokenControllerimplements
/oauth/token,/oauth/userinfo,/oauth/introspect, and/oauth/revoke.JWTs are signed with an RS256 keypair loaded from env; users and API keys share one
principal model with role claims.
Acceptance Criteria.
src/auth-oidc/provides issuance/verification.ApiKeyGuardcontinues to acceptx-api-key; new routes use@UseGuards(JwtAuthGuard).jti) prevents reuse of revoked tokens.Implementation Notes. Use
jose(low dep) and the existingRedismodule ratherthan rolling key management.
Files or modules likely to be affected.
src/auth-oidc/*(new),src/auth/*,src/common/guards/jwt-auth.guard.ts(new),app.module.ts.Dependencies. #4 (same Redis), #12 (revocation list).
Difficulty. Hard
Estimated effort. L
Backlog item #10 from `docs/maintainer-issue-backlog.md.