# Access Token Service Low-Level Design: JWT Signing, Key Rotation, and Claim Customization

Source: https://www.techinterview.org/post/3233470575/lld-access-token-service/
Updated: 2026-07-13 · techinterview.org

## What Is an Access Token Service?

An access token service issues short-lived cryptographically signed tokens that authorize access to protected resources. JWTs (JSON Web Tokens) are the dominant format: self-contained, verifiable without a database lookup, and extensible via custom claims. The critical design concerns are algorithm selection for signing, JWKS endpoint exposure for public key distribution, safe key rotation without service interruption, and a flexible claim customization pipeline.

## Requirements

### Functional Requirements

- Issue signed JWTs with a configurable expiry (default 15 minutes) for authenticated principals.

- Support RS256 (RSA + SHA-256) and ES256 (ECDSA + P-256) signing algorithms.

- Expose a JWKS (JSON Web Key Set) endpoint so resource servers can verify tokens without calling the auth service on every request.

- Rotate signing keys on a schedule (default 30 days) without invalidating tokens issued under the previous key.

- Allow per-client claim customization: inject tenant_id, roles, scopes, and arbitrary metadata.

### Non-Functional Requirements

- Token issuance latency under 10 ms at p99.

- JWKS endpoint must be cacheable and available independently of the issuance path.

- Private keys must never appear in logs, error messages, or API responses.

## Data Model

### Signing Key Record

- **kid** — Key ID, UUID; included in JWT header so verifiers know which key to use.

- **algorithm** — RS256 or ES256.

- **private_key_ref** — reference to encrypted private key in a secrets manager (Vault, AWS KMS); never stored in plaintext in the database.

- **public_key_jwk** — serialized public key in JWK format; safe to store and serve.

- **status** — ENUM: `ACTIVE`, `RETIRING`, `RETIRED`.

- **created_at**, **retire_at**, **delete_at**.

### Token Issuance Log (optional, for audit)

- **jti** — JWT ID, unique per token; enables revocation lookup.

- **sub**, **client_id**, **issued_at**, **expires_at**, **kid**.

## Core Algorithm: Token Issuance

### Step 1 — Principal Verification

Receive an authenticated request (valid session cookie, client credentials, or authorization code). Extract the principal identity and client context.

### Step 2 — Claim Assembly

Build the standard claims: `iss` (issuer URL), `sub` (subject), `aud` (audience), `iat`, `exp`, `jti`. Invoke the claim customization pipeline: load per-client claim rules from a configuration store, evaluate each rule against the principal context, and merge custom claims (roles, scopes, tenant_id, feature flags) into the payload. Validate that no reserved claims are overwritten by custom rules.

### Step 3 — Signing

Retrieve the current ACTIVE signing key. Fetch the private key from the secrets manager (cache the decrypted key object in-process for the key lifetime to avoid per-token KMS calls). Sign the JWT using the selected algorithm. Include `kid` in the JOSE header. Return the compact serialization.

## Key Rotation Algorithm

Key rotation must not interrupt verification: resource servers cache the JWKS with a short TTL (5 minutes) and must be able to verify tokens issued under both the old and new key during the overlap period.

- **T-7 days**: Generate new key pair. Set status to `ACTIVE`. Add to JWKS. Old key moves to `RETIRING` (still in JWKS, still valid for verification).

- **T+0 (rotation day)**: New key becomes the default signing key. All new tokens use the new kid.

- **T+max_token_lifetime**: Old key moves to `RETIRED`. Remove from JWKS. Tokens signed with it are now expired anyway.

- **delete_at**: Remove private key from secrets manager. Retain public key record for audit.

## JWKS Endpoint Design

Serve `GET /.well-known/jwks.json` as a static JSON document containing all ACTIVE and RETIRING public keys. Set `Cache-Control: max-age=300, stale-while-revalidate=60`. Resource servers should implement a key refresh on encountering an unknown kid rather than hard-failing, enabling zero-downtime rotation. The JWKS document should be served from a CDN or edge cache to handle high verification traffic without hitting the auth service.

## API Design

- **POST /token** — issue an access token; accepts grant_type, client credentials or authorization code.

- **GET /.well-known/jwks.json** — public key set for token verification.

- **GET /.well-known/openid-configuration** — discovery document pointing to JWKS and token endpoints.

- **POST /token/introspect** — active/inactive check for opaque token compatibility (optional).

- **POST /admin/keys/rotate** — trigger manual key rotation (admin-only, protected by mTLS).

## Scalability Considerations

Token issuance is CPU-bound (RSA signing is more expensive than ECDSA; prefer ES256 for high-throughput scenarios). Cache the loaded private key object in-process to eliminate KMS round-trips. Run multiple stateless issuance instances behind a load balancer; all share the same signing key fetched from a central secrets manager. The JWKS endpoint is read-only and cacheable; serve it from a CDN with 5-minute TTL and origin shield to handle millions of verifications per second without load on the auth service.

See also: [Netflix Interview Guide 2026: Streaming Architecture, Recommendation Systems, and Engineering Excellence](https://www.techinterview.org/post/3233460274/netflix-interview-guide-2026-streaming-architecture-recommendation-systems-and-engineering-excellence/)

See also: [Scale AI Interview Guide 2026: Data Infrastructure, RLHF Pipelines, and ML Engineering](https://www.techinterview.org/post/3233460275/scale-ai-interview-guide-2026-data-infrastructure-rlhf-pipelines-and-ml-engineering/)

See also: [Stripe Interview Guide 2026: Process, Bug Bash Round, and Payment Systems](https://www.techinterview.org/post/3233460268/stripe-interview-guide-2026-process-bug-bash-round-and-payment-systems/)
