OAuth 2.0 is an authorization framework. It answers:
How can an application get permission to call an API without learning (or storing) the user’s password?
OAuth is also the foundation for most modern identity flows (OIDC builds on it). If you work with any IdP, API gateway, CIAM, mobile app, or SaaS integration, you’re living in OAuth.
The cast of characters (roles)
OAuth 2.0 defines four roles:
- Resource Owner: the user (or sometimes an admin) who can grant access
- Client: the app that wants access (web app, SPA, mobile app, CLI)
- Authorization Server (AS): issues tokens after authenticating user and gathering consent
- Resource Server (RS): the API that validates tokens and serves data
Trust boundaries
- The AS is where the user authenticates and where consent happens.
- The RS should not trust the client—only the token (and its validation).
What gets exchanged (artifacts)
- Authorization Code: short-lived one-time code returned to the client (via redirect)
- Access Token: presented to the API (usually a bearer token)
- Refresh Token: used to mint new access tokens (high-value secret)
- Scope: the permissions being requested
- State: CSRF protection for redirect-based flows
Diagram: the Authorization Code flow (most common)
Diagram
Why this is the default: it keeps tokens off the front channel and gives you a clean place to add security controls.
Which flows should you actually use?
Authorization Code (+ PKCE)
- Use for: web apps, SPAs (yes), mobile apps, native apps
- Why: best security properties when paired with PKCE
Client Credentials
- Use for: machine-to-machine calls (service → service)
- Identity: the client itself (not a user)
Device Code
- Use for: CLIs/TVs where typing a password is awkward
Implicit
- Avoid: obsolete in modern guidance (replaced by code + PKCE)
Token validation: what an API must check
On the resource server side, don’t just “decode a JWT and trust it.” You must validate.
Minimum checks:
- signature is valid (right key)
- issuer (
iss) is the expected AS - audience (
aud) matches your API - expiration (
exp) is not expired (allow small clock skew) - scope/claims authorize the requested operation
If your access tokens are opaque, you typically validate via introspection (online) or an API gateway.
Common production failure modes
invalid_redirect_uri(mismatch between request and registered URI)- “works in dev, fails in prod” due to different issuer/tenant
- missing/incorrect PKCE verifier
- token accepted by one API but rejected by another (wrong
aud) - refresh tokens stored in logs, browser storage, or support tickets
Security hardening (modern IAM guidance)
- Prefer Authorization Code + PKCE everywhere.
- Keep access tokens short-lived.
- Treat refresh tokens like secrets (rotation + revocation).
- Constrain tokens (audience restrictions, DPoP/mTLS where possible).
Related:
- OAuth hardening: /topic/specifications/oauth-2-1-best-practices-pkce-rotation-threat-model
- Token theft response: /topic/specifications/oauth-token-security-revocation-rotation-incident-response
