OAuth 2.0 (RFC 6749, 2012) is an authorisation delegation framework — not an authentication protocol — that solves a specific problem: how does a user grant a third-party application access to their resources on a server, without giving that application their password? The canonical example is a user granting a calendar app access to their Google Drive files: OAuth 2.0 lets Google issue the calendar app a scoped, time-limited access token that permits it to read Drive files, without the app ever seeing the user’s Google password. The distinction between authorisation and authentication is fundamental: OAuth 2.0 proves that a token was issued by an authorisation server for a specific scope — it says nothing about who the user is. Attempting to use OAuth 2.0 for authentication (treating token possession as proof of identity) is a well-documented anti-pattern with concrete exploits; OIDC (OpenID Connect) is the authentication layer built on top of OAuth 2.0 that addresses this correctly.
The protocol defines an authorisation server (AS — the party that issues tokens, e.g. Google, GitHub, Okta, Keycloak), a resource server (RS — the API that accepts tokens and returns protected resources), a client (the application requesting access), and a resource owner (the user whose resources are being accessed). OAuth 2.0 defines several grant types — flows by which a client obtains tokens — appropriate for different client architectures. The Authorization Code grant is the standard flow for user-facing applications: the client redirects the user to the AS, the user authenticates and consents, the AS redirects back with a short-lived authorisation code, and the client exchanges that code for tokens at the token endpoint. PKCE (Proof Key for Code Exchange, RFC 7636) is a mandatory extension for public clients (SPAs, mobile apps) that cannot safely hold a client secret: the client generates a random code_verifier, sends a code_challenge (SHA-256 hash of the verifier) with the authorisation request, and proves possession of the verifier at token exchange, preventing authorisation code interception attacks. Client Credentials is the machine-to-machine grant: a client authenticates directly to the token endpoint with its own credentials (client ID + secret, or a client certificate for mTLS-based client authentication per RFC 8705) and receives an access token scoped to its own identity, with no user involved — the standard pattern for service-to-service API access. Device Authorization (RFC 8628) handles input-constrained devices (smart TVs, CLI tools) that cannot open a browser: the device displays a short code and URL, the user authenticates on a second device, and the device polls for the resulting token. The Implicit and Resource Owner Password Credentials grants are deprecated in OAuth 2.1 (the forthcoming consolidation of OAuth 2.0 best practices) and should not be used in new deployments.
Access tokens in modern OAuth 2.0 deployments are typically JWTs (JSON Web Tokens, RFC 7519): a base64url-encoded JSON header (algorithm, key ID) + payload (issuer iss, subject sub, audience aud, expiry exp, issued-at iat, scope scp, and custom claims) + signature (RS256/ES256/EdDSA produced by the AS’s signing key). A resource server validates a JWT access token by verifying the signature against the AS’s published public key (retrieved from the AS’s JWKS endpoint at /.well-known/oauth-authorization-server), checking the exp claim, confirming the aud matches its own identifier, and checking the scp or scope claim against the operation being requested. Opaque tokens are an alternative — a random string that the RS must validate by calling the AS’s introspection endpoint (RFC 7662) per request, trading RS statelessness for AS-controlled revocation. Token lifetimes are a security/UX trade-off: short-lived access tokens (5–15 minutes) limit the damage from token leakage; refresh tokens (RFC 6749 §6) allow the client to obtain new access tokens without re-involving the user, and are themselves long-lived but should be sender-constrained (via mTLS or DPoP, RFC 9449) to prevent use from a different client if stolen. In the Vault and SPIFFE/SPIRE context, OAuth 2.0 client credentials flows with mTLS client authentication or JWT client assertions (RFC 7523 — using a JWT signed with the client’s private key as the credential, rather than a shared secret) are the standard machine-to-machine access pattern; SPIRE’s OIDC federation endpoint issues JWT-SVIDs that can be used directly as RFC 7523 client assertions with cloud provider token endpoints (AWS STS, GCP STS), enabling workload identity without any static secret.
