Skip to content

Session Security: Refresh-Token Rotation with Reuse Detection, jti Revocation, kid-Based Key Rotation, Claims Hygiene #345

Description

@Christopherdominic

Summary

Session security in src/services/auth_service.rs is a single static HS256 secret with structural gaps:

  • No token revocation — logout, password change, or account compromise cannot invalidate already-issued access tokens; they remain valid until expiry.
  • No refresh-token rotation or reuse detection — a stolen refresh token is replayable in parallel with the legitimate client indefinitely, and the theft is undetectable.
  • No key rotation — one JWT_SECRET forever; rotating it invalidates every session simultaneously and there is no kid-based overlap.
  • No standard claims hygieneaud/iss validation and explicit clock-skew leeway are not enforced.

Task

  1. Refresh-token rotation with reuse detection: every refresh issues a new refresh token and invalidates the old one; presenting an already-rotated token (theft indicator) revokes the entire token family and forces re-authentication. Persist token families with device metadata (new migration).
  2. Access-token revocation: short-lived access tokens (≤15 min) plus a Redis denylist keyed by jti, populated on logout / password change / admin revocation / family compromise, checked in middleware/auth.rs with a fail-closed policy and a latency budget (denylist check must be a single Redis round-trip).
  3. kid-based key rotation: sign with the current key, verify against an active key set from config; an admin rotation flow allows overlap until old-key tokens age out. Document the runbook in docs/.
  4. Claims hygiene: enforce iss, aud, nbf, bounded exp, and explicit leeway; reject algorithm confusion by pinning the algorithm allowlist at decode.
  5. Session management endpoints: list active sessions/devices for a user, revoke one, revoke all (wired into the existing admin surface).
  6. Tests: rotation happy path; reuse-detection kills the family (the critical test); revoked jti rejected within one propagation round-trip; old-key verification during rotation overlap; algorithm-confusion attempt rejected; clock-skew boundary.

Acceptance criteria

  • Stolen-refresh-token replay is detected and the family revoked (tested)
  • Logout/password-change invalidates outstanding access tokens (tested)
  • Key rotation possible with zero forced global logout (tested with overlapping keys)
  • aud/iss/algorithm pinning enforced
  • All checks pass

PR requirements (mandatory)

  • ✅ Your PR must pass all checks — PRs with failing or skipped checks will not be merged.
  • 📸 You must attach a screenshot in the PR description demonstrating the result (for this issue: the reuse-detection test output and a demonstration of session revocation taking effect).
  • 🔗 You must link this issue number in your PR description (e.g. Closes #<issue-number>). PRs without a linked issue will not be reviewed.

Metadata

Metadata

Assignees

Labels

GrantFox OSSIssue tracked in GrantFox OSSMaybe RewardedIssue may be eligible for a GrantFox rewardOfficial Campaign | FWC26Campaign: Official Campaign | FWC26difficulty: very hardRequires deep expertise and substantial effortsecuritySecurity hardening or vulnerability work

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions