API Authentication Patterns
debt(d5/e7/b7/t7)
Closest to 'specialist tool catches it' (d5). The term's detection_hints list semgrep and owasp-zap as tools that can catch common misuses like API keys in query parameters, unsigned JWTs (alg:none), and missing token expiry. These are specialist SAST/DAST tools, not default linters. Some issues like insufficient token scoping or missing revocation strategies require careful code review, pushing toward d7, but the automated detection of the most common code patterns (confirmed automated: yes) keeps this at d5.
Closest to 'cross-cutting refactor across the codebase' (e7). The quick_fix is a conceptual guideline ('use the simplest pattern that meets your requirements'), not a one-line replacement. Switching from one auth pattern to another (e.g., from long-lived API keys to JWT + refresh tokens, or adding OAuth2 for delegated access) requires changes across authentication middleware, token issuance, token validation, client code, and often database schema for refresh token/blocklist storage. This is inherently cross-cutting. Not quite e9 because it doesn't necessarily require a full architectural rewrite — it's a significant but bounded refactor.
Closest to 'strong gravitational pull' (b7). Authentication pattern choice applies to web and API contexts and shapes every endpoint's security model, middleware stack, session management, and client integration. Per the tags (api-design, security, auth), this is a load-bearing architectural decision. Every new endpoint, every new service-to-service call, and every client must conform to the chosen auth pattern. It doesn't quite define the entire system's shape (b9) since other architectural dimensions exist independently, but it strongly shapes every change involving access control.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field is explicit: developers believe 'JWT authentication is stateless and therefore cannot be revoked,' which is a half-truth that leads to dangerous design decisions (no blocklist, long-lived tokens). Additional common_mistakes like accepting alg:none tokens and putting API keys in query parameters are traps where the 'obvious' approach (just pass the key as a parameter, trust the JWT header) is wrong. The JWT statelessness misconception is particularly insidious because 'stateless' is marketed as a feature, leading developers to skip revocation mechanisms entirely.
Also Known As
TL;DR
Explanation
API authentication options: Bearer token (Authorization: Bearer jwt) — stateless JWT, validate signature/expiry/issuer; use short expiry (15min) + refresh tokens. API key (X-API-Key header) — hash stored server-side, scope keys to minimum required permissions, rate-limit per key. Basic auth — only with HTTPS, legacy use only. OAuth 2.0 client credentials — for third-party apps accessing your API on their own behalf. mTLS (mutual TLS) — both client and server present certificates, no passwords, ideal for internal microservices. HMAC request signing (AWS Signature v4 style) — signs request body and headers, prevents replay attacks.
Common Misconception
Why It Matters
Common Mistakes
- Long-lived JWT tokens without revocation — a leaked token remains valid until expiry
- API keys in URL query parameters — logged by servers, CDNs, browser history, and proxies
- No token scoping — one token with full access means any leak is a full compromise
- JWT without signature validation — accepting unsigned tokens with alg:none
Avoid When
- Using API keys in URLs — they appear in server logs, browser history, and referrer headers.
- Long-lived tokens with no expiry or rotation — a stolen token is valid forever.
- Storing API keys in client-side JavaScript — they are visible to anyone who views source.
- Using HTTP Basic Auth over plain HTTP — credentials are sent in every request, base64-encoded but not encrypted.
When To Use
- API keys for server-to-server calls where the key can be stored securely in environment variables.
- OAuth 2.0 + PKCE for user-delegated access — never embed client secrets in mobile or SPA clients.
- JWT bearer tokens for stateless APIs where the token carries claims without server-side session lookup.
- mTLS for high-trust service-to-service communication in zero-trust network environments.
Code Examples
// Long-lived JWT — leaked token valid for 1 year:
$token = JWT::encode([
'sub' => $userId,
'exp' => time() + 31536000, // 1 year expiry!
], $secretKey);
// Leaked token: full access for up to 1 year
// API key in URL — logged everywhere:
GET /api/data?api_key=sk_live_abc123
// Short-lived access token + refresh token:
$access = JWT::encode(['sub'=>$userId,'exp'=>time()+900], $key); // 15 min
$refresh = JWT::encode(['sub'=>$userId,'exp'=>time()+2592000], $refreshKey); // 30 days
// Leaked access token: valid at most 15 min
// Refresh tokens: stored and rotatable
// API key in header — not logged by default:
// Authorization: Bearer $access
// OR: X-API-Key: sk_live_abc123