Introduction
Authentication services verify who the user is; authorization services control what they can do. A centralized auth service handles both concerns for all internal microservices, providing a single source of truth for identity and access policy. Rather than each service implementing its own auth logic, every service delegates token validation and permission checks to the shared auth layer.
OAuth 2.0 Flows
OAuth 2.0 defines several grant types matched to different trust levels and deployment contexts. Authorization Code with PKCE is used for web and mobile applications where a user agent is present: the client redirects the user to the authorization server, receives an authorization code, and exchanges it for tokens using a code verifier. PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks. Client Credentials is used for service-to-service calls where no user is involved: the service authenticates with its client_id and client_secret and receives an access token scoped to service permissions. The Implicit flow is deprecated and should not be used in new systems. Flows differ by trust level and whether a user agent is present. The authorization server issues an access_token (short-lived, 15 minutes) and a refresh_token (long-lived, 30 days) upon successful authentication.
JWT Access Tokens
JWTs are structured as header.payload.signature, Base64URL-encoded and dot-separated. The payload contains standard claims: sub (subject/user_id), iss (issuer), aud (audience), exp (expiration), iat (issued at), plus custom claims for scopes and roles. The signature is produced with RSA-256 or ECDSA-256 using the auth server’s private key. Stateless verification: any downstream service can verify the token by fetching the auth server’s public key from the JWKS endpoint and validating the signature locally — no DB lookup required. Key rotation: publish the new public key to the JWKS endpoint, continue signing with the new private key, old tokens remain valid until their exp claim, and new tokens are signed with the new key.
Session Management
Server-side sessions store a session_id in a cookie; the session data lives in Redis with a TTL. The advantage is instant revocation: deleting the Redis key immediately invalidates the session. The disadvantage is that every request requires a Redis lookup. Token-based sessions using JWTs carry no server state, enabling horizontal scaling without shared session storage, but revocation requires either a token blacklist (reintroducing state) or accepting that tokens are valid until expiry. A hybrid approach uses opaque reference tokens: the client holds a short random token stored in Redis, which maps to the full JWT claims. This gives instant revocation while keeping claims out of the cookie.
RBAC Authorization
Role-Based Access Control is modeled with four tables: Role (role_id, name, description), Permission (permission_id, resource, action), RolePermission (role_id, permission_id), and UserRole (user_id, role_id). A permission check asks: does this user have any role that includes the permission for resource:action? Results are cached per user after the first evaluation. For fine-grained control, Attribute-Based Access Control (ABAC) evaluates policies against attributes: for example, a policy might state subject.department == resource.department AND action == read, allowing access only when the user’s department matches the resource’s department.
Multi-Factor Authentication
TOTP (Time-based One-Time Password) is the standard MFA mechanism: the user registers an authenticator app (Google Authenticator, Authy) by scanning a QR code that encodes a shared TOTP secret. On login, the server verifies that the submitted code equals HOTP(secret, floor(current_time / 30)), accepting the current and previous time window to tolerate clock skew. Backup codes are generated at registration, stored as bcrypt hashes, and consumed one-time each. SMS OTP via Twilio is supported as a fallback but is less secure due to SIM-swap attacks and SS7 vulnerabilities.
Token Revocation
Access tokens are short-lived (15 minutes) — no active revocation is required; they expire quickly enough that the window of misuse is small. Refresh tokens are revocable: they are stored in the database with an is_revoked flag. On every refresh request, the server validates that the token is not revoked before issuing a new access token. Token family rotation adds stolen-token detection: each refresh operation issues a new refresh_token and invalidates the previous one. If the old (already-consumed) refresh_token is presented again, the entire token family is revoked, protecting the user if a refresh token was stolen and used.
SSO with SAML
SAML-based Single Sign-On connects a Service Provider (SP) to an Identity Provider (IdP). The flow: the user accesses a resource on the SP; the SP redirects the user to the IdP with a SAML AuthnRequest; the user authenticates at the IdP (using corporate credentials against Active Directory or Okta); the IdP posts a signed SAML response containing a SAML assertion to the SP’s Assertion Consumer Service URL; the SP validates the XML signature against the IdP’s certificate and creates a local session. SAML is the standard for enterprise SSO integration with existing corporate identity infrastructure.
Frequently Asked Questions: Authentication and Authorization Service Design
When should you use OAuth 2.0 Authorization Code with PKCE versus Client Credentials grant?
Use Authorization Code with PKCE for user-facing flows where a human delegates access — the PKCE code verifier prevents authorization code interception in public clients like SPAs and mobile apps. Use Client Credentials for machine-to-machine flows where no user is involved, such as a backend service calling another internal API with its own identity. PKCE eliminates the need for a client secret in public clients; Client Credentials requires a secret kept server-side.
How does JWT stateless verification differ from opaque token database lookup, and what are the tradeoffs?
JWT stateless verification lets any service validate a token by checking the signature against a public key — no network call required, which gives low latency and horizontal scalability. The tradeoff is that JWTs cannot be revoked before expiry; a compromised token remains valid until it expires. Opaque tokens are random strings that require a DB or cache lookup on every request to retrieve associated claims, adding latency but enabling instant revocation. Common hybrid: short-lived JWTs (5–15 min) with a revocation blocklist for high-value scenarios.
How do you implement TOTP-based MFA in an authentication service?
During enrollment, generate a 160-bit random secret per user, store it encrypted at rest, and present it as a QR code encoding an otpauth:// URI for apps like Google Authenticator. At verification, compute HMAC-SHA1 over the current 30-second time window counter concatenated with the secret, then extract a 6-digit code via dynamic truncation (RFC 6238). Accept the current window plus one window of clock drift. Rate-limit attempts and implement lockout to prevent brute force. Store each used OTP to prevent replay within the same window.
How does refresh token rotation help detect stolen tokens?
On each token refresh, issue a new refresh token and invalidate the old one. Store a refresh token family — all tokens derived from the original login event. If an already-used refresh token is presented (meaning an attacker stole and used it before the legitimate client could rotate), invalidate the entire family immediately, forcing re-authentication. This converts a stolen refresh token from a persistent credential into a one-time-use artifact and provides a signal of token theft when the legitimate client next attempts a refresh and gets rejected.
When should you choose SAML versus OIDC for enterprise SSO integration?
Choose SAML when integrating with legacy enterprise identity providers (e.g., ADFS, older Okta configurations) that only speak SAML 2.0, or when the SP requires XML-based assertions for compliance. Choose OIDC when building modern web or mobile apps — it uses JSON/JWT over REST, is simpler to implement, and natively supports OAuth 2.0 token flows for API authorization alongside authentication. OIDC is the default for greenfield integrations; SAML is retained for compatibility with established enterprise IdP deployments.
See also: Meta Interview Guide 2026: Facebook, Instagram, WhatsApp Engineering
See also: Coinbase Interview Guide