Zum Hauptinhalt springen

Token Lifecycle

Detailed documentation on JWT token structure, validation strategies, token rotation, and revocation.

JWT Payload Structure

Access tokens include the following claims for context-aware authorization:

ClaimDescription
idUser ID
tenantIdCurrent tenant scope
organizationIdCurrent organization context
employeeIdLinked employee ID (if applicable)
roleUser's role name
permissionsArray of enabled permissions
ipAddressClient IP at token issuance (device binding)
userAgentClient User-Agent at token issuance

Refresh tokens carry a subset: id, email, tenantId, organizationId, role, ipAddress, userAgent.

JWT Configuration

Token TypeEnvironment VariableExpiry
Access TokenJWT_SECRETConfigurable via JWT_TOKEN_EXPIRATION_TIME
Refresh TokenJWT_REFRESH_TOKEN_SECRETConfigurable via JWT_REFRESH_TOKEN_EXPIRATION_TIME
Email VerificationJWT_VERIFICATION_TOKEN_SECRETJWT_VERIFICATION_TOKEN_EXPIRATION_TIME
warning

The application will fail to start if JWT_SECRET, JWT_REFRESH_TOKEN_SECRET, or JWT_VERIFICATION_TOKEN_SECRET are missing or use insecure default values.

JWT Validation Strategy (JwtStrategy)

The JwtStrategy performs defense-in-depth validation beyond standard JWT signature checks:

  1. Employee cross-validation — If the token contains an employeeId, the strategy verifies the employee still exists and belongs to the claimed user.
  2. Organization membership — If the token contains an organizationId, the strategy validates the user is still a member of that organization.
  3. User existence — The user is re-fetched from the database with tenant and role relations to ensure the account is still active.

Refresh Token Strategy (JwtRefreshTokenStrategy)

The refresh token strategy adds an additional identity reconciliation check:

  1. Extracts the refresh token from the request body.
  2. Validates it via RefreshTokenService.verify() (which checks inactivity timeouts).
  3. Cross-checks the userId from the JWT payload against the userId from the verified token record — preventing token substitution attacks.
  4. Fetches and returns the full user object only after both checks pass.

Scoped Token Service (CQRS)

Both access and refresh tokens are managed by a Scoped Token Service backed by CQRS commands and queries:

OperationDescription
createTokenGenerates a new token with configurable metadata
rotateTokenAtomically revokes old token and issues new one
revokeTokenRevokes a specific token with reason tracking
revokeAllUserTokensRevokes all tokens of a given type for a user
validateTokenValidates token with optional inactivity check
getActiveTokensLists active tokens for a user

Token Rotation

When refresh tokens are rotated:

  1. The old token is validated (including inactivity check).
  2. If invalid, an UnauthorizedException is thrown.
  3. The old token is atomically revoked and a new token is issued.
  4. Organization context is preserved across rotations.

Logout

Logout performs parallel revocation of all active tokens:

  1. Removes the stored refresh token from the user record.
  2. Revokes the refresh token via RefreshTokenService.
  3. Revokes the current access token via AccessTokenService.

All three operations run concurrently via Promise.allSettled(). Individual failures are logged but do not block the logout flow.