OAuth is an authorization framework that governs delegated access to protected APIs.
OAuth 2.0, JWT, and API keys each solve a different API authentication problem. Treating them as interchangeable is how teams ship the wrong security model. Picking correctly requires understanding what each credential represents, how it is revoked, and what operational discipline it demands.
API Authentication: Three Competing Approaches

OAuth 2.0, JWT, and API keys each represent a distinct security model for controlling which callers can reach a protected API endpoint. JWT favors stateless authentication: the server verifies a signature rather than looking up session state. OAuth builds delegated authorization into the protocol, issuing scoped, short-lived tokens after a resource owner grants consent. API keys trade granular control for operational simplicity, identifying a known caller with a static secret. The table below frames where each method sits before the detail sections.
| Method | Token format | Revocation model | Best fit |
|---|---|---|---|
| JWT | Signed Base64url JSON | Short expiry; blocklist for early revocation | Stateless microservice auth, internal SSO |
| OAuth 2.0 | Opaque or JWT access token | Revocation endpoint; refresh token rotation | Third-party integrations, user-delegated access |
| API keys | Static opaque secret string | Manual rotation or key deletion | Server-to-server calls, simple machine clients |
How JWT Works
JWT (JSON Web Token) is a compact, self-contained credential format defined in RFC 7519 that encodes claims as a Base64url-encoded JSON payload signed with a signature algorithm such as RS256 or HMAC-SHA256. The signature covers the header and payload, so any modification to the claims invalidates it. Because the claims travel inside the token, a resource server can validate a JWT without any database lookup, which is the operational basis of stateless authentication. Token expiry is encoded in the exp claim: once that timestamp passes, the verifier rejects the credential.
RS256 (RSA + SHA-256) uses an asymmetric key pair: the issuer signs with a private key and any consumer verifies with the corresponding public key. HMAC variants such as HS256 use a shared secret, which restricts verification to parties that hold that secret. RS256 is the standard choice when multiple services must verify the same token independently. A JSON Web Token has three dot-separated components:
- Header: a JSON object declaring the token type and the signature algorithm in use, for example
{"alg":"RS256","typ":"JWT"}. The header tells the verifier which key and HMAC or asymmetric scheme to apply. - Payload: the Base64url-encoded claims set, containing registered fields such as
iss(issuer),sub(subject), andexp(token expiry timestamp), plus any custom application claims the issuer embeds. - Signature: the cryptographic digest over the encoded header and payload, produced with the signing key. The verifier recomputes it on every request to confirm authenticity and integrity.
If a JWT signing key is compromised, all tokens issued under it are compromised. Revocation without a blocklist relies entirely on waiting for the exp timestamp to pass, which is why short token expiry is the primary operational control for stateless authentication deployments.
How OAuth 2.0 Works

OAuth 2.0 is an authorization framework, defined in RFC 6749, that issues short-lived access tokens to client applications after a resource owner grants consent. The framework separates three roles: the resource owner who holds the data, the client requesting access, and the authorization server that issues the credential. The client never sees the user's password. It receives a scoped access token covering only what the user approved, and a refresh token it can use to silently obtain a new access token when the current one expires.
OpenID Connect (OIDC) is an identity layer built on top of OAuth that adds a signed ID token containing user identity claims. Where OAuth alone answers "what can this client do?", OIDC also answers "who authorized this?" Most modern identity providers issue JWT access tokens and OIDC ID tokens together in the same grant response, so the two protocols work as a pair in production deployments.
RFC 6749 defines four grant types for obtaining an access token:
- Authorization code: the client redirects the user to an authorization server, receives a short-lived code, and exchanges it server-side for an access token and a refresh token. The recommended flow for web and native apps; combined with PKCE (Proof Key for Code Exchange), it is secure for public clients that cannot protect a client secret.
- Implicit: the access token is returned directly in the redirect URI fragment, without a code-exchange step. Now discouraged in favor of the authorization code flow with PKCE, because the token is exposed in browser history and referrer headers.
- Resource Owner Password Credentials (ROPC): the client collects the user's username and password directly and exchanges them for an access token. A high-trust legacy flow, now discouraged except in controlled migration scenarios where redirecting to an authorization server is not feasible.
- Client credentials: the client authenticates with the authorization server using its own client ID and secret, receiving an access token scoped to the client itself. The standard choice for service-to-service calls with no user context.
The Device Authorization Grant, used for input-constrained clients such as smart TVs and CLI tools, is a separate extension defined in RFC 8628 and is not part of the RFC 6749 core framework. It works by displaying a short user code on the device while the user completes authorization on a separate browser-capable device, with the client polling the token endpoint until the grant succeeds.
How API Keys Work
OAuth and JWT are protocol-heavy by design; API keys offer a simpler credential model where a server-generated secret string is attached to every request for identity verification. The server maps the key to an account or service, checks it against a stored hash, and allows or rejects the request. There is no consent flow, no signature to verify, and no built-in expiry. That simplicity makes API keys appealing for internal API authentication between services a single team controls, and it is also the source of their risk profile.
The OWASP API Security project identifies broken authentication as a top risk category, and static API keys are a recurring contributor. Key risks to manage:
- No expiry by default: a leaked key stays valid until explicitly revoked. Without token expiry, credential rotation is the only defense, and it must be enforced operationally rather than by the protocol.
- No scope granularity: a single API key typically grants whatever the account can do. There is no mechanism to restrict it to one resource or one action short of custom application logic.
- Plaintext in transit risk: keys passed in query parameters appear in server logs, browser history, and CDN access logs. Transmission in the
Authorizationheader over TLS is the correct pattern, but it requires explicit enforcement. - Credential rotation discipline required: because keys carry no natural expiry, teams must schedule rotation proactively. Keys that outlive the engineers who created them remain active across environments until someone audits the key registry.
Security Model Comparison
OAuth carries the most sophisticated security model of the three, supporting token expiry, refresh token rotation, scopes, and revocation endpoints. The bearer token transport requirements in RFC 6750 mandate TLS for all bearer token transmissions and strongly discourage tokens in URI query strings (Section 2.3 uses SHOULD NOT, with a narrow exception when the Authorization header is infeasible), establishing a baseline that many API key implementations routinely violate. JWT's stateless authentication trades revocation granularity for verification speed: the resource server needs no central state to validate a signed token, but revocation without a blocklist means waiting for the exp claim to lapse. API keys provide no built-in token expiry and no scope enforcement unless those controls are added at the API gateway level.
| Security dimension | JWT | OAuth 2.0 | API keys |
|---|---|---|---|
| Revocation | Blocklist required; no native revocation | Revocation endpoint; refresh token rotation | Manual key deletion or rotation |
| Expiry enforcement | Built-in exp claim enforced by verifier | Short-lived access token plus refresh token lifecycle | None by default; manual rotation only |
| Scope granularity | Custom claims; no standard scope model | Native scopes defined per authorization grant | All-or-nothing per key unless gateway-enforced |
| Credential rotation | Key rollover; no client config change required | Refresh token rotation; silent re-authorization | New key must be distributed to all consumers |
| Server state required | None (stateless); blocklist adds state | Token store plus optional revocation endpoint | Key registry required |
| Third-party integration | Possible but lacks a delegated authorization protocol | Native delegated authorization via consent flow | Not designed for third-party delegation |
The pattern is clear once revocation and scope enter the picture. JWT optimizes for verification speed and accepts weaker revocation as the cost. API keys optimize for setup simplicity and accept the absence of expiry and scope. OAuth pays a complexity tax in exchange for the controls that matter most when an external party holds a long-lived credential.
Choosing the Right Authentication Method
OAuth is the right choice when your API must support third-party integrations, delegated authorization, or per-user scoped permissions. The client credentials grant makes it a clean fit for service-to-service calls as well, giving you the same revocation and scope machinery without the redirect flow. JWT-only flows work well inside a controlled service mesh where the issuer and all verifiers are under the same operational team. API keys remain the lowest-friction option for simple machine clients with no user context, provided credential rotation is enforced by policy rather than left to individual developers.
The API gateway comparison covers how Kong, AWS API Gateway, and Zuul each handle token validation and key authentication at the edge, which affects which credential model is practical to enforce at scale. For teams building the underlying service, the building a REST API in Python guide covers how Flask, Django REST Framework, and FastAPI each expose middleware hooks for plugging in token validation logic.
- Service-to-service, internal calls
- Recommended method: JWT (stateless authentication) or OAuth client credentials. JWT eliminates per-request latency from a token introspection call; OAuth client credentials add a revocation endpoint when the authorization server is already in your infrastructure. Store signing keys or client secrets in a secrets manager with automated credential rotation, not in environment variables committed to source control.
- User-facing, third-party integrations
- Recommended method: OAuth 2.0 authorization code with PKCE, issuing JWT access tokens. This is the only model that supports delegated authorization without exposing user credentials to the client. Scopes constrain what the third party can access, and refresh token rotation limits the damage window of a compromised credential. Pair with OpenID Connect when the integration also needs verified user identity claims.
- Simple machine client with no user context
- Recommended method: API keys backed by a secrets manager with a defined credential rotation schedule. When the caller is a server under your control, calling a first-party API, and the integration requires no per-user scoping, the protocol overhead of OAuth is not justified. Assign each integration a dedicated key, store it in a vault, and rotate on a fixed schedule. The API testing tools comparison covers how Postman, Insomnia, and Thunder Client handle API key and bearer token injection for development and local testing workflows.
References
- RFC 7519: JSON Web Token (JWT)
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 6750: Bearer Token Usage
- RFC 8628: OAuth 2.0 Device Authorization Grant
- OWASP API Security Top 10
Further reading
Frequently Asked Questions
What is the main difference between JWT and OAuth?
JWT is a token format used to represent claims securely between two parties, while OAuth 2.0 is an authorization framework that governs how access is granted. JWT is often used as the token format inside an OAuth 2.0 flow, meaning the two are complementary, not mutually exclusive. The key distinction is that JWT describes the structure of a credential, whereas OAuth 2.0 describes the protocol for obtaining one.
Are API keys secure for authentication?
API keys provide adequate security for server-to-server calls where the key is stored in a secrets manager and never exposed in client-side code. They become a liability when rotated infrequently, transmitted in query parameters, or shared across environments. For user-facing flows or sensitive data, OAuth with short-lived access tokens offers a significantly stronger security model.
Can JWT be used with OAuth?
Yes. OAuth 2.0 defines the authorization flow but leaves the token format open to implementers. RFC 9068 formalizes JWT as a bearer token format for OAuth, and most modern identity providers issue JWTs as their OAuth access tokens. Using JWT with OAuth gives you both delegated authorization and stateless token verification.
What grant types does OAuth 2.0 define?
RFC 6749 defines four OAuth 2.0 grant types. They are: authorization code (for web and native apps), implicit (now discouraged in favor of authorization code with PKCE), Resource Owner Password Credentials (a legacy high-trust flow), and client credentials (for service-to-service calls). The Device Authorization Grant, used for input-constrained clients such as smart TVs, is a separate extension defined in RFC 8628 and is not part of the RFC 6749 core framework.
How do I choose the best authentication method for my API?
Start with your trust model: if callers are internal services with no user context, API keys with server-side rotation are the simplest fit. If your API serves end users or requires scoped permissions per resource, OAuth with JWT access tokens is the appropriate choice. Reserve JWT-only flows for stateless microservice-to-microservice calls where you control both issuer and verifier and have no need for a delegation protocol.









