Skip to content

JWT issuance and revocation via OIDC for frontend (and JWT backend) #218

Description

@kilodesodiq-arch

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.

Metadata

Metadata

Assignees

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions