Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ricardomb-tech/auth-service/llms.txt

Use this file to discover all available pages before exploring further.

Auth Service uses a two-token model: a short-lived JWT access token that downstream services can validate locally without a database round-trip, and an opaque refresh token that is stored (as a hash) in the database and can be used once to obtain a new token pair. Together they provide stateless request authentication with the ability to revoke sessions and detect token theft.

Access tokens

Access tokens are JSON Web Tokens signed with HS256 using the secret configured via JWT_SECRET_CURRENT. They are fully stateless — Auth Service does not persist them and does not maintain a revocation list for them. Validation by a downstream service requires only the shared secret, the expected issuer, and a check of the exp claim. TTL: 15 minutes (expiresInSeconds: 900).

JWT payload

{
  "sub": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "email": "user@example.com",
  "roles": ["USER"],
  "iat": 1700000000,
  "exp": 1700000900,
  "iss": "auth-service"
}
ClaimTypeDescription
substring (UUID)The account’s unique identifier. Use this as the stable user reference in downstream services.
emailstringThe account’s verified email address at the time the token was issued.
rolesstring[]Array of role names assigned to the account. Values: USER, ADMIN.
iatnumberIssued-at timestamp (Unix epoch, seconds).
expnumberExpiry timestamp (Unix epoch, seconds). Exactly iat + 900.
issstringAlways "auth-service". Downstream services must validate this value.

Refresh tokens

Refresh tokens are cryptographically random opaque strings. Auth Service stores only the SHA-256 hash of each token in the database — the raw value is never persisted. This means a database breach does not expose usable refresh tokens. TTL: 7 days from issuance.
Tracking: every refresh token belongs to a family — a lineage of tokens derived from the same original login event. Families enable the reuse-detection mechanism described below.

Rotate a token pair

Exchange a valid refresh token for a new access token and a new refresh token. The old refresh token is immediately marked as consumed and cannot be used again.
curl -X POST https://your-auth-service/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "d3f4a2b1c9e8..."
  }'
Response — 200 OK
{
  "accessToken": "eyJhbGciOiJIUzI1NiJ9...",
  "refreshToken": "f7a9b3c2d1e0...",
  "tokenType": "Bearer",
  "expiresInSeconds": 900
}
Both the new access token and the new refresh token replace the old pair. Store them, discard the old values, and use the new refreshToken in subsequent rotation calls.
Implement proactive refresh in your client: schedule a token rotation request a minute or two before the access token’s 15-minute TTL expires, rather than waiting for a 401 response. This produces a smoother user experience and avoids a request-failure-then-retry cycle for users with active sessions.

Reuse detection and family revocation

If a refresh token that has already been consumed is presented to /auth/refresh, Auth Service treats this as evidence of token theft — either the original holder or the attacker is replaying a stolen token.
Presenting a consumed refresh token immediately revokes the entire token family. All active refresh tokens in that family (including any legitimately issued successors) are invalidated. The affected user will receive a 401 and must log in again from scratch. This is intentional: it is safer to force a re-login than to allow an attacker with a stolen token to silently maintain access.
The reuse check happens before expiry and revocation checks. A consumed token triggers family revocation even if it also happens to be expired.

Logout

Revoke a refresh token by posting it to /auth/logout. This marks the token as revoked in the database, preventing future rotations with that token.
curl -X POST https://your-auth-service/auth/logout \
  -H "Content-Type: application/json" \
  -d '{
    "refreshToken": "d3f4a2b1c9e8..."
  }'
Response — 204 No Content Logout is idempotent: presenting an already-revoked, expired, or unknown token returns 204 No Content — never an error. Clients can safely call logout even if they are unsure whether the token is still valid.
Logging out does not invalidate the access token — it is stateless and cannot be revoked individually. After logout, the access token remains usable until its 15-minute TTL expires. For high-security scenarios, keep the access token TTL short and ensure downstream services always validate the exp claim.

JWT secret rotation

Auth Service supports zero-downtime secret rotation via a pair of environment variables:
VariableDescription
JWT_SECRET_CURRENTThe active signing secret. All new tokens are signed with this key.
JWT_SECRET_PREVIOUSThe previous signing secret. Tokens signed with this key are still accepted during the rotation window.
During rotation, set JWT_SECRET_PREVIOUS to the old value of JWT_SECRET_CURRENT, then update JWT_SECRET_CURRENT to the new secret. Existing tokens signed with the old key remain valid until they expire. Once all old tokens have expired, JWT_SECRET_PREVIOUS can be cleared.

Build docs developers (and LLMs) love