Skip to content

FAC-83 feat: make JWT token expiry and refresh token settings configurable via env vars #180

@y4nder

Description

@y4nder

Summary

Several JWT-related values are currently hardcoded in the codebase with no way to tune them without a code change. These should be promoted to environment variables with sensible defaults so that token lifetimes and security parameters can be adjusted per environment (dev, staging, prod) without rebuilding.

Current State

Setting Hardcoded value Location
Access token expiry '300s' (5 min) src/modules/index.module.ts:54
Refresh token expiry '30d' (30 days) src/modules/common/custom-jwt-service/index.ts:36
Refresh token bcrypt salt rounds 10 src/modules/common/custom-jwt-service/index.ts

JWT_SECRET and REFRESH_SECRET are already env-driven. This issue covers the remaining hardcoded knobs.

Desired State

Introduce three optional env vars validated in src/configurations/env/jwt.env.ts:

Env var Default Description
JWT_ACCESS_TOKEN_EXPIRY 300s Access token lifetime (any value accepted by jsonwebtoken expiresIn)
JWT_REFRESH_TOKEN_EXPIRY 30d Refresh token lifetime — must stay consistent with RefreshToken.expiresAt DB calculation
JWT_BCRYPT_ROUNDS 10 Bcrypt cost factor for hashing refresh tokens in the DB

Acceptance Criteria

  • Zod schema in jwt.env.ts validates all three new vars with appropriate defaults
  • index.module.ts reads JWT_ACCESS_TOKEN_EXPIRY instead of the string literal
  • CustomJwtService reads JWT_REFRESH_TOKEN_EXPIRY for both the JWT expiresIn and the expiresAt date stored in the RefreshToken entity (they must stay in sync)
  • CustomJwtService reads JWT_BCRYPT_ROUNDS for bcrypt hashing
  • .env.sample documents all three new vars as optional with their defaults
  • CLAUDE.md env-vars table updated

Notes

  • The expiresAt field on RefreshToken is currently calculated separately from the JWT expiry string — both must derive from the same source to avoid drift (e.g. parse the duration string into milliseconds once).
  • JWT_BCRYPT_ROUNDS should be validated as a positive integer; values below 10 should log a warning in non-production environments.

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions