Skip to content

Per-client token signing algorithm configuration (support ES384; keys per tenant+alg) #86

@rowan-stein

Description

@rowan-stein

User Request

Add client-level configuration to select JWT signature algorithms for ID tokens and access tokens. Must support ES384. Avoid env vars; configuration must live on the OAuth/OIDC Client model. Multiple clients under the same tenant should be able to use different algorithms concurrently.

Researcher Spec

Models and flows

  • Clients: Prisma model Client with clientId (OIDC client_id). Token issuance obtains client via consumeAuthorizationCode(...) and issueTokensFromCode(...).
  • Tokens: Both id_token and access_token are JWTs currently signed with RS256.
  • Keys: TenantKey persists per-tenant signing keys (private encrypted, public JWKS), currently RS256-only.

Proposed changes

  1. Client model fields (Prisma):

    • Add enum:
      enum JwtSigningAlg { RS256 PS256 ES256 ES384 }
    • Add fields:
      idTokenSignedResponseAlg JwtSigningAlg?
      accessTokenSigningAlg    JwtSigningAlg?
    • Validation: accept only supported enum values.
  2. Algorithm resolution (issuance):

    • id token alg = client.idTokenSignedResponseAlg ?? RS256.
    • access token alg = client.accessTokenSigningAlg ?? id token alg.
  3. Key management per (tenant, alg):

    • Maintain one ACTIVE key per (tenantId, alg); auto-generate on first use.
    • Update key-service to:
      • getActiveKey(tenantId, alg)
      • ensureActiveKeyForAlg(tenantId, alg)
      • rotateKeyForAlg(tenantId, alg) using generateKeyPair(alg, { extractable: true }).
    • JWKS publishes all ACTIVE and ROTATED keys across algorithms.
  4. Signing and verification:

    • Token issuance: set JWT header { alg: resolvedAlg, kid } and import JWK with that alg.
    • Verification (e.g., userinfo-service): decode header, use header.alg to importJWK and verify; reject unsupported/missing alg.
  5. Discovery:

    • Advertise full supported list (including ES384) in id_token_signing_alg_values_supported.

Files to update

  • prisma/schema.prisma: add enum, client fields; index on TenantKey(tenantId, alg, status).
  • src/server/services/key-service.ts: per-tenant+alg active key functions.
  • src/server/services/token-service.ts: resolve algs per client; ensure key; sign with resolved algs.
  • src/server/services/userinfo-service.ts: verify using JWT header alg.
  • src/server/services/discovery-service.ts: advertise supported list.
  • src/server/services/client-service.ts + src/app/admin/actions.ts + client admin UI: add update/display for new fields.
  • Tests: extend OIDC flow and unit tests for ES384 and multi-client algs.

Acceptance Criteria

  • Client model holds id_token_signed_response_alg and access_token_signing_alg (stored as enum fields).
  • ES384 works for both tokens when configured; default remains RS256.
  • Tenants can have ACTIVE keys per algorithm; JWKS publishes multiple keys; verification uses header alg.
  • Discovery lists supported algorithms including ES384.
  • Tests cover two clients in one tenant using different algs concurrently.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions