Authentication & Authorization — Compute Reference
1. At a glance
Authentication (AuthN) answers who you are. Authorization (AuthZ) answers what you can do. Together they form the identity layer of every modern system — from a single web app login to a cross-cloud zero-trust mesh.
The modern stack converges on a small set of building blocks:
- OpenID Connect (OIDC) for browser, mobile, and native user login (identity layer on top of OAuth 2.0).
- OAuth 2.0 / 2.1 for delegated API access — third-party apps, mobile clients, machine-to-machine.
- SAML 2.0 for legacy enterprise SSO — still dominant in B2B SaaS in 2026 because corporate IdPs (Okta, ADFS, Entra) still default to it for federation.
- FIDO2 / WebAuthn / passkeys for passwordless, phishing-resistant user authentication.
- mTLS for service-to-service authentication in zero-trust networks.
- JWT as the token format for ID tokens, access tokens, and increasingly internal claims.
Authorization splits into RBAC (roles, simple), ABAC (attributes/policies, flexible), ReBAC (relationship graphs, fine-grained at scale — popularized by Google’s 2019 Zanzibar paper), and PBAC (policy-as-code via OPA Rego or AWS Cedar).
The unifying principle since Google’s 2014 BeyondCorp paper is zero-trust: never trust the network; verify identity, device, and context on every request.
This note is a working reference — terminology, RFC numbers, real product names, and the pitfalls you need to know before shipping.
2. Authentication factors
Authentication factors are traditionally categorized into three classes:
- Knowledge — something you know. Passwords, PINs, security-question answers, recovery codes.
- Possession — something you have. TOTP token on a phone, hardware security key, signed device certificate, push-notification approval, SIM (SMS, but weak).
- Inherence — something you are. Fingerprint, FaceID, iris scan, voiceprint, behavioral biometrics (typing cadence, gait).
A fourth and fifth class are sometimes cited:
- Location — somewhere you are. IP geolocation, GPS, corporate network segment.
- Behavior — something you do. Usage patterns, mouse movement, transaction history.
Multi-factor authentication (MFA) combines two or more factors from different classes. A password plus a security question is still single-factor (both knowledge). A password plus a TOTP code is true MFA.
Step-up authentication raises the bar for higher-risk operations: a normal session may require only a password and a remembered device, but transferring money or changing email triggers a fresh WebAuthn assertion. Auth0, Okta, and Stytch all expose step-up primitives.
Continuous / adaptive authentication treats trust as a sliding score evaluated on every request — device posture, geolocation, time of day, typing cadence — rather than a single login event. This is the operating model for zero-trust gateways like Cloudflare Access and Google IAP.
3. Passwords
Despite two decades of attempts to kill them, passwords remain the universal fallback. Doing them correctly is a solved problem; doing them incorrectly leaks credentials at industrial scale.
Hashing
- Argon2id is the current best practice. It won the Password Hashing Competition in 2015 and is RFC 9106 (2021). Resistant to GPU, ASIC, and side-channel attacks. Recommended parameters as of 2026:
m=64 MiB, t=3, p=1for interactive logins; raisemandtto taste. - bcrypt (1999) remains acceptable as a fallback. Use cost factor ≥10 (≥12 for new deployments). Note the 72-byte password length cap — pre-hash long passwords with SHA-256 if needed.
- scrypt (RFC 7914, 2016) is fine but less common than Argon2id.
- PBKDF2 (RFC 2898) is still permitted by NIST and FIPS for compliance contexts. Use SHA-256 or SHA-512, ≥600,000 iterations as of OWASP 2023 guidance.
What not to use
- Plain SHA-256, SHA-1, MD5 — too fast on commodity GPUs. A single RTX 4090 cracks raw SHA-256 at roughly 10 GH/s; a multi-GPU rig brute-forces an 8-character alphanumeric password in hours.
- Unsalted hashes — enables rainbow-table attacks and reveals identical passwords across users.
- Custom “homegrown” stretching — never compose your own KDF.
Password policy (NIST SP 800-63B-4, 2024 draft)
NIST’s modernized guidance, refined since the 2017 revision and now in 2024 draft form as SP 800-63-4 Revision 4:
- Minimum 8 characters for user-chosen passwords, 6 for system-generated.
- Maximum at least 64 characters (allow long passphrases).
- No composition rules — don’t require an uppercase + symbol + digit. Composition rules push users to predictable patterns (
Password1!). - No periodic forced rotation unless there’s evidence of compromise.
- Check candidate passwords against breach lists. The HaveIBeenPwned Pwned Passwords API exposes ~850M compromised hashes via a k-anonymity range query.
- Allow all printable ASCII and Unicode; do not silently truncate.
- Permit (and encourage) password managers — don’t block paste.
- Rate-limit and throttle login endpoints; lock or CAPTCHA after repeated failures from a source.
Storage
The PHC string format ($argon2id$v=19$m=65536,t=3,p=1$<salt>$<hash>) bundles algorithm, parameters, salt, and digest in a single field. Standard across libraries (libsodium, argon2-cffi, bcrypt, passlib, phpass). Per-user salt is mandatory; pepper (server-side secret added before hashing) is a defense-in-depth bonus and should live in a KMS or HSM, not in source.
4. TOTP and HOTP
HOTP (HMAC-based One-Time Password, RFC 4226, 2005) — counter-based. Shared secret + monotonically increasing counter; user and server must stay in sync. Used in some legacy hardware tokens (RSA SecurID variants, YubiKey OATH-HOTP).
TOTP (Time-based One-Time Password, RFC 6238, 2011) — time-based variant. Code = HMAC-SHA1(secret, floor(time / 30s)) truncated to 6 digits. The 30-second window and clock-skew tolerance (±1 step) make TOTP the dominant 2FA option in consumer and enterprise.
Common authenticator apps:
- Google Authenticator — ubiquitous; added cloud sync 2023.
- Microsoft Authenticator — push approval for Entra ID, plus TOTP.
- Authy (Twilio) — multi-device, cloud-synced; consumer app retired 2024 in favor of API SDK.
- Aegis (FOSS, Android) — encrypted local vault, no cloud.
- Raivo OTP (FOSS, iOS) — local + iCloud backup.
- 1Password, Bitwarden, Proton Pass — password managers with built-in TOTP.
TOTP secrets are typically provisioned via a otpauth:// URI encoded in a QR code. Format:
otpauth://totp/Issuer:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Issuer&algorithm=SHA1&digits=6&period=30
Weaknesses of TOTP: the shared secret is bearer-style — anyone who scrapes it from a phishing page can impersonate the user. TOTP is not phishing-resistant. WebAuthn is.
5. WebAuthn, FIDO2, and passkeys
FIDO2 is the umbrella term for the FIDO Alliance’s modern authentication stack, made up of two specs:
- W3C WebAuthn (Web Authentication API) — JavaScript API exposed to browsers and native platforms. Level 1 became a W3C Recommendation in March 2019; Level 2 in April 2021; Level 3 in 2023 with PRF extension, conditional UI, and cross-origin support.
- CTAP2 (Client-To-Authenticator Protocol) — wire protocol between platform (browser/OS) and authenticator (security key or platform module) over USB-HID, NFC, or BLE.
The flow is challenge-response over public-key cryptography:
- Registration: client generates a fresh keypair on the authenticator (Secure Enclave, TPM, security key). Private key never leaves the device. Public key + attestation are sent to the relying party (RP).
- Authentication: RP sends a random challenge; authenticator signs
(challenge || rpID || clientDataJSON)with the private key after user gesture (touch, biometric, PIN). Signature is verified by RP using the stored public key.
The signed rpID (the origin scope) is the source of phishing resistance: a credential bound to bank.com will refuse to sign a challenge from bаnk.com (look-alike domain) because the browser computes the actual origin and feeds it into the signature.
Authenticator types
- Platform authenticators — built into the device. Apple Secure Enclave (Touch ID / Face ID), Android Keystore + StrongBox, Windows Hello (TPM-backed). Bound to the device.
- Roaming authenticators — external. YubiKey 5 / Bio / C, Google Titan, SoloKey v2, Nitrokey 3, Feitian, Token2.
- Hybrid (caBLE / CTAP-over-BLE-and-Cloud) — phone-as-authenticator via Bluetooth proximity check plus a tunnel server. Used by passkey-sync flows.
Resident keys vs non-resident credentials
A resident key (a.k.a. discoverable credential) is stored on the authenticator itself with a username binding, enabling truly passwordless flows: the user clicks “Sign in,” the browser asks the authenticator which accounts it knows about, and the user picks one. Non-resident credentials live encrypted as an opaque blob in the relying party’s database; the RP must already know the user’s identifier and ask the authenticator to use a specific key.
Passkeys (FIDO Alliance, May 2022)
A passkey is a WebAuthn credential that is multi-device synced through a cloud provider:
- iCloud Keychain — Apple devices; synced end-to-end encrypted across iPhone, iPad, Mac.
- Google Password Manager — Android + Chrome; synced through the Google account.
- Windows Hello / Microsoft Account — synced across signed-in Windows 11+ devices.
- 1Password, Bitwarden, Dashlane, Proton Pass — third-party password managers acting as passkey providers via the Credential Management API (Chrome) or AutoFill Credential Provider extension (iOS/macOS/Windows).
Passkeys lose pure device-binding (a copy lives in the cloud) in exchange for usability — losing one device doesn’t lock out the user. Device-bound passkeys (synced=false) remain available for compliance or step-up.
Browser and OS support (2026)
Chrome, Edge, Safari, Firefox, and all major mobile browsers support WebAuthn Level 2 fully and Level 3 partially. Conditional UI (“sign in” autofill prompt that surfaces passkeys) shipped in Chrome 108, Safari 16, and Firefox 119.
Libraries
- JS client:
@simplewebauthn/browser, nativenavigator.credentials.create/get. - Server:
@simplewebauthn/server(TS),py_webauthn(Python),webauthn4j(Java),go-webauthn(Go),webauthn-rs(Rust).
6. OAuth 2.0 and OAuth 2.1
OAuth 2.0 (RFC 6749, 2012) — Dick Hartt’s framework for delegated authorization. The often-confused tagline: OAuth is about authorization, not authentication. Use OIDC if you need to identify the user.
OAuth 2.1 — the IETF Working Group’s consolidation draft (active through 2024–2026) that folds in a decade of best-current-practice RFCs and removes deprecated flows.
Core flows
- Authorization Code + PKCE (RFC 7636, 2015) — the modern default. The browser/app redirects to the authorization server, user authenticates, server returns a code, client exchanges code (plus PKCE verifier) for tokens. Required for SPAs and native/mobile apps; recommended even for confidential server-side clients.
- Client Credentials — service-to-service. Client authenticates with its own credentials and gets an access token. No user involved.
- Refresh Token — long-lived token traded for a new access token. Always rotate refresh tokens in OAuth 2.1; a used refresh token invalidates instantly, and reuse triggers session revocation.
- Device Authorization Grant (RFC 8628) — for devices without a browser (TV, CLI). User goes to a URL on another device and enters a code.
- CIBA (Client-Initiated Backchannel Authentication) — server pushes auth prompt to user’s phone; used in fintech and telecom.
Deprecated flows (don’t use)
- Implicit flow — returned access tokens directly in the URL fragment. Broken against modern threat model (tokens leak into referer, history, logs). Removed in OAuth 2.1.
- Resource Owner Password Credentials (ROPC) — user gives their password to the client app, which forwards it. Defeats the whole point of OAuth. Removed in OAuth 2.1.
Tokens
- Access token — short-lived (5–60 min typically), bearer (RFC 6750) by default. Format is implementation-defined; commonly JWT but can be opaque (introspected).
- Refresh token — longer-lived (hours to months), used only at the token endpoint, must rotate.
- ID token — OIDC-specific (see §7).
Related specs
- RFC 6749 — core OAuth 2.0 framework.
- RFC 6750 — bearer token usage.
- RFC 6819 — threat model and security considerations.
- RFC 7009 — token revocation.
- RFC 7591 / 7592 — dynamic client registration and management.
- RFC 7636 — PKCE.
- RFC 7662 — token introspection (server-side validation of opaque tokens).
- RFC 8252 — OAuth for native apps (BCP).
- RFC 8414 — authorization server metadata discovery.
- RFC 8628 — device authorization grant.
- RFC 8693 — token exchange (used in delegation, impersonation, on-behalf-of).
- RFC 8705 — mTLS client authentication and certificate-bound tokens.
- RFC 9068 — JWT profile for OAuth 2.0 access tokens (the canonical “access token as JWT” spec).
- RFC 9126 — Pushed Authorization Requests (PAR).
- RFC 9396 — Rich Authorization Requests (RAR) — granular scopes beyond
scope=read write. - RFC 9449 (DPoP, 2023) — Demonstration of Proof-of-Possession: bind a token to a client-side key by signing each request. Mitigates token theft without requiring mTLS.
PKCE in 60 seconds
verifier = random 43–128 chars [A-Za-z0-9-._~]
challenge = base64url(SHA-256(verifier))
→ /authorize?code_challenge=<challenge>&code_challenge_method=S256
← redirect_uri?code=<auth_code>
→ /token body: code=<auth_code>&code_verifier=<verifier>
← {access_token, refresh_token, id_token, ...}
PKCE prevents a malicious app on the same device from intercepting the redirect and exchanging the auth code: the attacker has the code but not the verifier.
7. OpenID Connect (OIDC)
OIDC (final spec 2014, edited by Sakimura, Bradley, Jones, de Medeiros, Mortimore) is the thin identity layer over OAuth 2.0. The big additions:
- ID Token — a JWT containing claims about the user’s authentication event. Sent alongside the access token from the token endpoint.
- UserInfo endpoint — separate endpoint, called with the access token, returning user profile claims.
- Standardized scopes —
openid(required),profile,email,address,phone,offline_access(refresh token). - Discovery (
.well-known/openid-configuration) — JSON metadata document at the issuer URL listing endpoints, supported algorithms, scopes, response types. - JWKS endpoint — JSON Web Key Set; public keys used to verify signed tokens.
Standard ID token claims (RFC 7519 + OIDC Core §2)
| Claim | Meaning |
|---|---|
iss | Issuer identifier (must match expected IdP URL) |
sub | Subject — stable user identifier within the issuer |
aud | Audience — client ID(s) the token is intended for |
exp | Expiration time (seconds since epoch) |
iat | Issued-at time |
nbf | Not-before time |
auth_time | When the user authenticated |
nonce | Replay-protection value the client sent in the auth request |
acr / amr | Authentication context class / methods (e.g. urn:mace:incommon:iap:bronze, ["pwd", "otp"]) |
name, email, picture, locale | Profile claims when requested |
Critical validation steps
- Verify the JWT signature using the issuer’s JWKS (cache keys; respect
Cache-Control). - Check
issmatches expected issuer. - Check
audcontains yourclient_id. - Check
expandnbf. - Check
noncematches the one you sent. - If using hybrid or implicit-ish flows, also check
at_hashandc_hash.
Skipping any of these is how login bypasses happen — the 2018 GitLab CVE was a missing iss check.
Sibling specs
- OIDC Discovery 1.0 —
.well-known/openid-configuration. - OIDC Dynamic Client Registration —
/registerendpoint. - OIDC Session Management 1.0 — front-channel logout signaling.
- OIDC Back-Channel Logout — direct logout token POST to client.
- OIDC Front-Channel Logout — iframe-based logout broadcast.
- OIDC RP-Initiated Logout —
/end_sessionredirect. - OIDC Federation 1.0 — multilateral federation for governments and education (eIDAS, eduGAIN).
- FAPI (Financial-grade API) 1.0 / 2.0 — hardened OAuth/OIDC profile for open banking (UK Open Banking, FDX, Berlin Group, Brazil Open Finance). Mandates PKCE, JAR, PAR, mTLS or DPoP, signed responses.
8. SAML 2.0
SAML 2.0 — OASIS Standard, March 2005. XML-based federation predating OAuth and OIDC. Still ubiquitous in enterprise SaaS because corporate IdPs (Okta, ADFS, Microsoft Entra, OneLogin, PingFederate) and HR systems (Workday) defaulted to it for two decades.
Roles
- Identity Provider (IdP) — authenticates the user, mints assertions.
- Service Provider (SP) — the application receiving the assertion.
- User Agent — usually the browser; passes signed messages between IdP and SP.
Flows
- SP-initiated SSO — user hits the SP; SP redirects to IdP with a SAML AuthnRequest; IdP authenticates user; IdP POSTs assertion back to SP’s ACS (Assertion Consumer Service) URL.
- IdP-initiated SSO — user clicks an app icon on the IdP’s portal; IdP POSTs an unsolicited assertion to the SP. Convenient but vulnerable to replay if SP doesn’t enforce
InResponseToor short window.
Bindings
- HTTP Redirect — message DEFLATE-compressed and URL-encoded in query string. Used for short requests.
- HTTP POST — message base64-encoded in an HTML form auto-submitted via JavaScript. Used for assertions.
- HTTP Artifact — SP receives an artifact reference and resolves it via a back-channel SOAP call.
- SOAP — SAML over SOAP, used by older enterprise integrations.
Assertions
A SAML assertion is an XML document containing:
Subject— who.Conditions— when (NotBefore,NotOnOrAfter), audience restriction.AuthnStatement— how the user authenticated, when.AttributeStatement— claims (email, groups, employee ID, etc.).Signature— XML-DSig over the assertion or response.- Optionally
EncryptedAssertion— XML-Enc envelope.
Common pitfalls
- XML Signature Wrapping (XSW) — moving the signed assertion to a different XML position so the SP validates one element and processes another. Repeatedly broken implementations (Salesforce, Shibboleth, OneLogin) historically. Use a vetted library:
python3-saml,passport-saml,OneLogin/ruby-saml,pac4j,Spring Security SAML. - XXE (XML External Entity) in XML parser — disable external entity resolution.
- Missing
InResponseTocheck allowing replay of stolen assertions. - Accepting unsigned assertions — always require signature on assertion and on response if vendor’s metadata says so.
- Accepting any
NameIDrather than mapping via a trusted attribute.
OAuth/OIDC is preferred for new B2C; SAML remains the lingua franca for B2B SSO into SaaS. WorkOS, Auth0, Stytch SSO, Frontegg, and SSOJet exist to wrap SAML behind a single OIDC-style API for SaaS vendors.
9. JSON Web Tokens (JWT)
JWT (RFC 7519, 2015) — a compact, URL-safe representation of claims as header.payload.signature (or header.encrypted_key.iv.ciphertext.tag for JWE).
Companion RFCs:
- RFC 7515 — JWS (signing).
- RFC 7516 — JWE (encryption).
- RFC 7517 — JWK (key representation).
- RFC 7518 — JWA (algorithms).
- RFC 7519 — JWT (claim format).
- RFC 7638 — JWK Thumbprint.
- RFC 8725 — JWT Best Current Practices.
Signing algorithms
| Family | Algs | Notes |
|---|---|---|
| HMAC | HS256, HS384, HS512 | Symmetric; secret shared. Vulnerable to alg-confusion if you also accept asymmetric. |
| RSA | RS256, RS384, RS512, PS256, PS384, PS512 | Asymmetric. PS* (RSA-PSS) preferred over RS* (PKCS#1 v1.5). |
| ECDSA | ES256, ES384, ES512 | NIST curves P-256/384/521. |
| EdDSA | EdDSA (RFC 8037) | Ed25519 / Ed448. Fast, no nonce reuse pitfalls. Best modern choice. |
| none | none | Plaintext — never accept. |
Classic pitfalls
alg=noneaccepted — early jsonwebtoken-style bugs let an attacker drop the signature and setalg=none. Always whitelist accepted algorithms server-side.- Algorithm confusion — endpoint accepts both HMAC and RSA; attacker sends an HS256 token signed with the public key as the HMAC secret. Defense: pin the alg per key, or use separate verifiers per type.
jku/x5u/kidheader SSRF — JWT headers can point at arbitrary URLs or local files for key lookup. Defense: ignorejku/x5u, validatekidagainst an allowlist.- Weak HMAC secrets —
secret,password,changeme. Trivially brute-forced withhashcat -m 16500. Use ≥256 bits of entropy. - No expiration / generous
exp— short-lived (5–15 min) plus rotated refresh. - Missing audience check — same signer, multiple services, attacker reuses a token from service A against service B.
- PII in payload — JWT is signed, not encrypted. Don’t put SSNs in there. Use JWE if you must.
- No revocation strategy — signed tokens are valid until expiry. Use opaque tokens + Redis if you need immediate revocation; or maintain a blacklist keyed by
jti.
Library recommendations
jose(Filip Skokan, TypeScript) — best-in-class, strict by default.PyJWT(Python) — careful withalgorithms=kwarg.python-jose— older, less strict, preferauthliborjose.nimbus-jose-jwt(Java) — used by Spring Security.jjwt(Java) — Okta-maintained.golang-jwt/jwt(Go) — successor todgrijalva/jwt-go.jsonwebtoken(Rust).
Always pass an explicit algorithms parameter to decode/verify.
When not to use JWT for sessions
JWTs are stateless — great for distributed systems, terrible for revocation. If you need:
- Immediate logout (compromised account, password change).
- Per-request permission updates.
- Session listing / admin invalidation.
…use opaque tokens (random IDs) backed by Redis or a session store. JWT shines for short-lived access tokens, cross-service claim propagation, and OIDC ID tokens.
10. mTLS for service-to-service
Mutual TLS extends the standard TLS handshake so both endpoints present X.509 certificates. The server validates the client cert against a trusted CA, just as the client validates the server.
mTLS is the default authentication primitive in zero-trust service meshes:
- Istio — issues SVIDs (workload identity certs) signed by the in-cluster CA (Citadel/Istiod), rotated every 24h by default; sidecar envoy proxies enforce.
- Linkerd — same model with rust-based
linkerd2-proxy; identity issued by the Linkerd identity controller. - Consul Connect — HashiCorp’s mesh; issues certs from Consul CA or Vault.
- Cilium Service Mesh — eBPF-based; can use SPIFFE identities directly.
- AWS App Mesh, Kuma, Open Service Mesh.
SPIFFE and SPIRE
SPIFFE (Secure Production Identity Framework For Everyone) is a CNCF spec for workload identity:
- SPIFFE ID — URI like
spiffe://example.org/ns/prod/sa/payments. - SVID (SPIFFE Verifiable Identity Document) — the cert or JWT carrying the ID.
- Workload API — local UNIX socket through which workloads fetch their current SVID.
SPIRE is the reference implementation. The SPIRE Server runs in-cluster; SPIRE Agents on each node attest workloads (via Kubernetes ServiceAccount, AWS IID, GCP IIT, Docker labels) and hand out short-lived SVIDs through the local Workload API.
Cert lifecycle
Manual cert distribution doesn’t scale. Use:
- cert-manager (CNCF) — Kubernetes operator issuing certs from ACME (Let’s Encrypt, ZeroSSL), Vault, Venafi, internal CAs.
- Trust Manager — distributes trust bundles to namespaces.
- HashiCorp Vault PKI engine — programmatic issuance with TTLs.
- AWS Private CA — managed CA for VPC workloads.
- Smallstep
step-ca— lightweight private CA.
Best practice: cert TTLs in hours, not years. Rotation is the security control; long TTLs defeat the model.
11. API authentication patterns
| Pattern | Use case | Pros | Cons |
|---|---|---|---|
Bearer JWT in Authorization: Bearer <token> | Modern REST / GraphQL | Stateless, federatable | Revocation hard, theft = full impersonation |
| Bearer opaque token | Internal APIs needing fast revocation | Easy revoke | Requires introspection or session lookup |
| API key (static) | Server-to-server, tier identification | Trivial to implement | Long-lived secrets, replay risk |
| HMAC-signed request (AWS SigV4, Stripe webhooks) | Webhooks, low-latency machine clients | Tamper-evident, replay-resistant with nonce/timestamp | Implementation complexity, clock skew |
| OAuth client credentials | Service-to-service with central authz | Centralized, scoped, rotatable | Token endpoint dependency |
| mTLS client cert | Internal zero-trust, regulated industries | Strong identity, automatable, no token theft | Cert lifecycle ops |
| DPoP-bound JWT (RFC 9449) | Public-client APIs needing PoP | Mitigates token theft without mTLS | Newer; library support uneven |
| WebAuthn assertion for high-stakes API calls | Privileged admin / treasury / IRMA | Phishing-resistant, user gesture required | UX friction |
AWS SigV4 pattern
The canonical “HMAC-signed request” recipe:
- Construct a canonical request: method, URI, query string, headers, hashed payload.
- Construct a string-to-sign: algorithm, timestamp, scope, hash of canonical request.
- Derive a signing key:
HMAC(HMAC(HMAC(HMAC("AWS4" + secretKey, date), region), service), "aws4_request"). - Compute
signature = HMAC(signingKey, stringToSign). - Send via
Authorization: AWS4-HMAC-SHA256 Credential=... SignedHeaders=... Signature=....
Adopted in spirit by Stripe (Stripe-Signature header on webhooks), GitHub (X-Hub-Signature-256), Shopify, Slack, and most webhook providers.
12. Authorization models
RBAC — Role-Based Access Control
Users → Roles → Permissions. Standardized in NIST RBAC (1992) and ANSI INCITS 359-2004.
- Simple to reason about.
- Easy to audit.
- Scales poorly when permissions need to depend on resource attributes or relationships (e.g., “can edit this document because they’re the owner”).
- Combinatorial explosion: every new permission dimension multiplies role count.
Examples: Kubernetes RBAC (Role + RoleBinding + ClusterRole), traditional Active Directory groups, GitHub repo roles.
ABAC — Attribute-Based Access Control
Policy evaluates over attributes: subject.department == resource.owner_department AND env.time in business_hours AND action == "read".
- XACML 3.0 (OASIS 2013) — XML policy language. Powerful, verbose, fading.
- AWS IAM — JSON statement language with
Principal,Action,Resource,Condition. Effectively ABAC. - AWS Cedar (open-sourced 2023) — strongly typed policy language with formal verification, used in AWS Verified Permissions.
Strengths: flexible, context-aware. Weakness: policies sprawl; reasoning across them at scale needs tooling.
ReBAC — Relationship-Based Access Control
Model permissions as relationships in a graph: user:alice editor doc:42, group:eng member user:alice. Access checks become graph queries.
Originated in Google’s 2019 Zanzibar paper (Pang et al., USENIX ATC 2019) — describes the system Google uses to centralize permissions for YouTube, Drive, Photos, Calendar, and most internal services. Key properties:
- Consistency — Zanzibar provides snapshot reads through “zookies” (encoded timestamps); clients pass a zookie from a write to subsequent reads to ensure they see the effect.
- Latency — global p95 of 10ms with 95th percentile < 20ms across 10+ datacenters.
- Scale — trillions of relation tuples, millions of QPS.
Open-source Zanzibar-inspired systems (2022–2026):
- SpiceDB (Authzed) — Go, gRPC, the most mature open OSS. Permissions DSL.
- OpenFGA (Auth0/Okta, donated to CNCF) — Go, OpenAPI; sandbox playground.
- Permify — Go; SQL or KV backed.
- Warrant — Go (acquired by WorkOS 2023).
- Topaz (Aserto) — Go + edge-deployed.
- Auth0 FGA — managed OpenFGA-based offering.
ReBAC shines when permissions are transitive and resource-graph-shaped (orgs → teams → projects → documents → comments). It collapses what would be combinatorial ABAC policy into a small set of relation definitions.
PBAC — Policy-Based Access Control (policy-as-code)
- OPA — Open Policy Agent (CNCF, 2018) — Rego policy language; deployed as a sidecar or library to evaluate decisions. Used in Kubernetes admission control (Gatekeeper, Kyverno-Rego), Istio, Envoy, Terraform Cloud, microservice authz.
- AWS Cedar — typed, analyzable policy language; backs AWS Verified Permissions and an open-source eval engine.
- Casbin — multi-language library implementing several models (RBAC, ABAC, ACL) via a config-driven model definition.
- Styra DAS — commercial control plane for OPA.
Capability-based access control
A capability = an unforgeable reference + the rights to operate on it. Distinct from ACLs where the system looks up rights from identity. Examples:
- UNIX file descriptors (kind of).
- Capability-secure languages: Pony, E.
- Macaroons (Birgisson et al., Google 2014) — bearer tokens with embedded caveats (constraints) that can be attenuated client-side without server contact.
13. Authorization servers and IdPs
Cloud-managed
- Auth0 (acquired by Okta 2021, IPO Apr 2021 before acquisition) — consumer + B2B; OIDC + SAML + custom Actions/Rules + FGA.
- Okta — workforce IAM market leader; Universal Directory, Workflows, SCIM.
- Microsoft Entra ID (rebranded from Azure AD in 2023) — dominant in Microsoft-shop enterprises; Conditional Access; Entra External ID for CIAM.
- Google Cloud Identity / Identity Platform — Google account + custom OIDC.
- Amazon Cognito — User Pools (OIDC) + Identity Pools (federated AWS creds).
- AWS IAM Identity Center (former SSO).
- JumpCloud, OneLogin, Ping Identity, PingOne, ForgeRock (acquired by Thoma Bravo 2023), CyberArk (Idaptive), Centrify.
Self-hostable open source
- Keycloak (Red Hat) — Java, full-featured (OIDC, SAML, user federation, account console).
- Ory stack — Hydra (OIDC), Kratos (user mgmt), Keto (Zanzibar-style permissions), Oathkeeper (zero-trust proxy). Each is a separate Go service.
- Authelia — Go; SSO + 2FA portal in front of nginx/Traefik.
- Authentik — Python/Django; modern Keycloak alternative.
- ZITADEL — Go; OIDC + SAML + management API; multi-tenant.
- Casdoor — Go; open-source UI-first IdP.
- FusionAuth — Java; freemium with paid features.
- Dex (CNCF) — Go; thin OIDC connector for upstream IdPs.
- Pomerium — Go; identity-aware zero-trust proxy.
Developer-first / CIAM
- Clerk — React-first; UI components + hosted user mgmt.
- WorkOS — B2B-focused; SAML SSO, SCIM, Directory Sync, AuditLog, FGA as a single API.
- Stytch — passwordless-first (magic links, OTP, passkeys); B2C and B2B SaaS plans.
- Supabase Auth — bundled with Supabase Postgres; GoTrue under the hood.
- Firebase Auth / Identity Platform — Google’s CIAM, OIDC + SAML.
- Frontegg — B2B multi-tenant CIAM.
- Logto — open-source OIDC + developer UX.
- Descope — drag-and-drop auth flows.
- Hanko — passkey-first OSS.
- Magic, Web3Auth — wallet/social-login bridges for crypto.
14. SCIM — System for Cross-domain Identity Management
SCIM 2.0 (RFC 7642 requirements, RFC 7643 core schema, RFC 7644 protocol, 2015) — automated user and group provisioning across SaaS apps.
- Endpoints:
/Users,/Groups,/Schemas,/ResourceTypes,/ServiceProviderConfig,/Bulk. - Operations: standard REST verbs (
GET,POST,PUT,PATCH,DELETE) plus filter syntax (filter=userName eq "alice@example.com"). - PATCH: JSON Patch-style (
add,replace,remove) operations.
Common deployments:
- Okta as source, target SaaS apps as SCIM destinations.
- Microsoft Entra ID SCIM provisioning.
- OneLogin, JumpCloud, Rippling, Workday as sources.
- WorkOS Directory Sync abstracts vendor SCIM differences for B2B SaaS vendors.
SCIM removes the deprovisioning gap: HR fires user → IdP disables → SCIM propagates active=false to every downstream app within minutes. Critical for SOC 2 / ISO 27001 / HIPAA.
15. Session management
Cookies done right
Set every session cookie with:
HttpOnly— JS can’t read it (mitigates XSS exfiltration).Secure— only sent over HTTPS.SameSite=Lax(default safe) orSameSite=Strict(max safety, breaks some flows) orSameSite=None; Secure(only when you genuinely need cross-site cookies).__Host-prefix —__Host-session=...requiresSecure,Path=/, noDomain. Locks the cookie to a single origin.__Secure-prefix — requiresSecure.- Short
Max-Ageor noMax-Age(session cookie) for high-stakes; refresh server-side.
Server-side store
For revocable sessions:
- Redis — fast, TTLs, easy invalidation.
- Memcached — no persistence, just cache.
- Database table — fine at small scale; index on session ID; use prepared statements.
- Distributed session store — Redis Cluster, ElastiCache, Upstash, KeyDB, DragonflyDB.
Idle vs absolute timeout
- Idle timeout — extend on activity; expire after N minutes of inactivity. Typical: 15–30 min for sensitive apps, 8–24h for low-risk.
- Absolute timeout — hard expiry regardless of activity (typical 12h–7d). Force reauth.
CSRF defenses
Cross-Site Request Forgery is the cousin of session hijacking — attacker tricks a logged-in user’s browser into making a state-changing request.
SameSite=Laxcookies — default in modern browsers; blocks most CSRF.- Synchronizer token pattern — server issues a random token, expects it back in form or header on every state-changing request.
- Double-submit cookie — token in cookie and header/form field; server compares them.
- Origin / Referer check — verify request origin matches expected.
- Custom request header (
X-Requested-With: XMLHttpRequest) — fetch/XHR can set; cross-origin forms cannot.
Use SameSite + one of the token mechanisms; defense in depth.
16. Zero-trust
BeyondCorp — Google’s 2014 USENIX ;login: paper described moving the security perimeter from the network to identified, authenticated users and devices on every request. Foundational papers:
- Ward & Beyer, “BeyondCorp: A New Approach to Enterprise Security,” 2014.
- Osborn et al., “BeyondCorp: Design to Deployment at Google,” 2016.
- Cittadini et al., “BeyondCorp: The Access Proxy,” 2016.
NIST formalized the model in SP 800-207 (Zero Trust Architecture, 2020): Policy Engine + Policy Administrator + Policy Enforcement Point evaluate trust on every connection.
Core principles:
- Verify explicitly — authenticate and authorize on identity + device posture + behavioral signals, every request.
- Least privilege — just-enough, just-in-time access.
- Assume breach — segment, encrypt, monitor; minimize blast radius.
Zero-trust network access (ZTNA) products (2026)
- Cloudflare Access (part of Zero Trust suite).
- Google IAP (Identity-Aware Proxy).
- AWS Verified Access.
- Tailscale — WireGuard mesh + identity-based ACLs; pioneered the “tailnet” model.
- Twingate — agent-based ZTNA with split-tunnel.
- Zscaler Private Access (ZPA).
- Netskope NPA.
- Banyan Security (acquired by SonicWall 2023).
- Perimeter 81 (acquired by Check Point 2023).
Device posture
- Kolide (acquired by 1Password 2024) — honest device security on macOS, Windows, Linux.
- Jamf, Intune, Workspace ONE — MDM with posture signals.
- Apple Managed Device Attestation, Android Play Integrity API.
ZTNA gateways consume posture as input to the policy decision: “Alice on a managed, encrypted, patched MacBook → grant; Alice on her personal phone → step-up MFA or deny.”
17. Service-account and workload identity
The cloud-native answer to “how does a pod talk to S3 without a baked-in access key.”
Kubernetes ServiceAccount + projected tokens
Since Kubernetes 1.21, each pod gets a short-lived (1h default) projected ServiceAccount JWT mounted at /var/run/secrets/kubernetes.io/serviceaccount/token. The token has aud, iss=https://kubernetes.default.svc.cluster.local, and sub=system:serviceaccount:ns:name.
Cloud federation
The cluster’s OIDC issuer URL is exposed publicly (or via a known JWKS endpoint); cloud IAM trusts it.
- AWS IRSA — IAM Roles for Service Accounts — annotate a ServiceAccount with
eks.amazonaws.com/role-arn; pods get an AWS STS-vended temporary credential. Available on EKS and self-managed witheks-pod-identity-webhook. - AWS Pod Identity (2023) — simpler successor; agent on each node exchanges the SA token for STS creds via local HTTP endpoint.
- GCP Workload Identity — bind a Kubernetes SA to a GCP IAM service account via
iam.gke.io/gcp-service-accountannotation; pods authenticate via the GKE metadata server. - Azure AD Workload Identity — federated identity credentials; SA token traded for Entra ID token; replaces the older AAD Pod Identity.
Outside Kubernetes
- GitHub Actions OIDC — workflow runs get a signed token (
aud=sts.amazonaws.com,sub=repo:owner/repo:ref:refs/heads/main) that AWS/GCP/Azure can trust without long-lived secrets. - GitLab CI OIDC — same idea.
- CircleCI OIDC, Buildkite OIDC, Vault JWT/OIDC auth method — all federate CI identities into cloud or Vault without static secrets.
SPIFFE / SPIRE again
Beyond meshes, SPIRE can issue SVIDs for any workload (VMs, bare metal, lambdas) by attesting them via TPM, cloud instance identity documents, or hardware attestation, then federating to OIDC-trusting cloud IAM. See §10.
18. Account recovery and security
The hardest part of an auth system isn’t login; it’s getting users back in when they lose access without letting an attacker do the same.
- Backup / recovery codes — one-time codes issued at MFA enrollment, printed or stored offline. Mark consumed; surface remaining count.
- Verified secondary email / phone — send a signed link or OTP. Phone (SMS) is vulnerable to SIM swap; phone is not a security boundary against motivated attackers.
- Knowledge-based authentication (KBA) — “first car,” “mother’s maiden name.” Considered weak by NIST 800-63-3+; many answers are publicly scrapable. Avoid for high-stakes.
- Trusted device recovery — sign in on a device you’re already logged in on and approve the new device. Apple’s iCloud uses this.
- Account recovery contacts — Apple’s mechanism: nominate a contact who can vouch for you. Distinct from social recovery for crypto.
- Social recovery / threshold signatures — used by smart-contract wallets (Argent, Safe{Wallet}, Eclipse, Coinbase Smart Wallet, Sequence). Configure 3-of-5 trusted parties (devices or contacts); compromise of any single party doesn’t grant access.
- Risk-based / adaptive authentication — Auth0 Attack Protection, Okta ThreatInsight, Stytch Strong CAPTCHA, Microsoft Entra Risk Detections. Anomaly detection (impossible travel, new device, Tor exit, breached password) triggers step-up MFA or block.
- Reauthentication for sensitive actions — even within an active session, require fresh authentication for password change, MFA enrollment, payment method change, export of personal data.
Audit and notify
- Email the user on every important event: new login from new device, MFA enrolled/removed, password changed, OAuth app authorized.
- Show “Active sessions” and “Devices” pages with one-click revoke.
- Maintain an immutable audit log (append-only, ideally on a separate service or signed chain) of admin actions.
19. Common pitfalls
A condensed list of the issues that show up most often in security review:
- Secrets in source control — API keys, DB passwords, signing secrets committed to git. Use HashiCorp Vault, AWS Secrets Manager, Google Secret Manager, Azure Key Vault, Doppler, Infisical, 1Password Secrets Automation. Pre-commit hooks:
gitleaks,trufflehog. CI: GitHub secret scanning, GitGuardian. - JWT
alg=noneaccepted — always whitelist algs server-side. - JWT alg-confusion (HS256 vs RS256) — pin alg per key; use libraries that disallow ambiguous verification.
- Missing CSRF on state-changing requests — see §15.
- OAuth implicit flow — deprecated in 2.1; never start a new project with it.
- Missing PKCE on public clients — required in 2.1.
- Loose CORS —
Access-Control-Allow-Origin: *combined withAccess-Control-Allow-Credentials: trueis invalid and most browsers refuse, butOrigin: *with credentials echoing back the requestor’s Origin without an allowlist is a common bypass. - Open redirects —
?redirect=https://attacker.comafter login. Allowlist redirect URIs strictly. - Refresh tokens without rotation — long-lived refresh tokens leaking via logs or browser history are a one-shot persistent compromise. Rotate; detect reuse; revoke session on reuse.
- Permissions cached too long — admin demotes user, user keeps editing for an hour. Cache TTLs ≤ minutes for permission decisions; use revocation events (Pub/Sub, Zanzibar invalidations).
- “Impersonate user” / “Login as customer” admin features without audit and reauth — gated by separate MFA prompt; full audit log; clear visual indication; cannot perform destructive actions.
- Logging tokens / passwords — strip from logs and exception traces. Express morgan default logs full URL; redact
?code=,?access_token=. Cloudflare and Datadog have built-in JWT scrubbing. - No rate limiting on auth endpoints — credential stuffing via residential proxies fills password lists in days. Throttle by IP, by username, by ASN; CAPTCHA after threshold; lockout with cooldown.
- TOTP / WebAuthn enrollment bypass — admin SSO or password reset flow that skips MFA. Audit every entry point.
- Same MFA for user and recovery — recovery codes that re-enable both password reset and MFA bypass.
- Session fixation — accepting an attacker-supplied session ID; always rotate session ID on login and on privilege escalation.
- Insufficient
aud/issvalidation — see §7. - Trusting
X-Forwarded-For— only trust headers from your known load balancer; otherwise an attacker spoofs to bypass IP-based rules. - SAML XSW — see §8. Always use a vetted library.
- mTLS without revocation — long-lived certs with no CRL / OCSP / short TTLs become bearer credentials. Keep TTLs short.
20. Standards references
OAuth / OIDC core:
- RFC 6749 — OAuth 2.0 framework (Hardt 2012).
- RFC 6750 — Bearer token usage (Jones, Hardt 2012).
- RFC 6819 — OAuth threat model and security considerations.
- RFC 7009 — Token revocation.
- RFC 7591 / 7592 — Dynamic client registration.
- RFC 7636 — PKCE.
- RFC 7662 — Token introspection.
- RFC 8252 — OAuth for native apps (BCP).
- RFC 8414 — Authorization server metadata.
- RFC 8628 — Device authorization grant.
- RFC 8693 — Token exchange.
- RFC 8705 — mTLS client auth + cert-bound tokens.
- RFC 9068 — JWT profile for OAuth 2.0 access tokens.
- RFC 9126 — Pushed authorization requests (PAR).
- RFC 9396 — Rich authorization requests (RAR).
- RFC 9449 — DPoP (proof-of-possession).
- draft-ietf-oauth-v2-1 — OAuth 2.1 consolidation.
- OpenID Connect Core 1.0 + Discovery + Session Management + Federation 1.0 (Sakimura, Bradley, Jones, de Medeiros, Mortimore 2014).
- FAPI 2.0 Security Profile (OpenID Foundation 2024).
JWT family:
- RFC 7515 — JWS.
- RFC 7516 — JWE.
- RFC 7517 — JWK.
- RFC 7518 — JWA.
- RFC 7519 — JWT.
- RFC 7521 / 7523 — JWT bearer assertions.
- RFC 7638 — JWK thumbprint.
- RFC 8037 — EdDSA for JOSE.
- RFC 8725 — JWT best current practices.
WebAuthn / FIDO:
- W3C WebAuthn Level 1 (March 2019), Level 2 (April 2021), Level 3 Recommendation (2023).
- CTAP 2.1 / 2.2 (FIDO Alliance).
- FIDO Alliance Passkey Spec (2022).
- FIDO2 server / metadata service specs.
SAML:
- OASIS SAML 2.0 Core (March 2005), Bindings, Profiles, Metadata.
SCIM:
- RFC 7642 (requirements), RFC 7643 (core schema), RFC 7644 (protocol).
NIST and government:
- NIST SP 800-63-4 Digital Identity Guidelines (2024 draft) —
-AEnrollment & Identity Proofing,-BAuthentication & Lifecycle,-CFederation & Assertions. - NIST SP 800-207 Zero Trust Architecture (2020).
- NIST SP 800-162 Guide to ABAC.
- NIST RBAC standard (1992; ANSI INCITS 359-2004).
- CISA Zero Trust Maturity Model 2.0 (2023).
Foundational papers:
- Pang et al., “Zanzibar: Google’s Consistent, Global Authorization System,” USENIX ATC 2019.
- Ward & Beyer, “BeyondCorp: A New Approach to Enterprise Security,” USENIX ;login: 2014.
- Birgisson et al., “Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud,” NDSS 2014.
- Recordon & Hardt, OAuth 1.0a / 2.0 evolution writings.
- Sakimura et al., OIDC drafts and final.
21. Cross-references
- cryptography-fundamentals — primitives underlying JWT signing, mTLS, password hashing, WebAuthn.
- _index — root index for the Compute reference set.
- kubernetes-deep — Kubernetes RBAC, workload identity, OIDC federation.
- containers-service-mesh — mTLS, Istio, Linkerd, SPIFFE/SPIRE in practice.
- networking-foundations — TLS, certificate chains, transport-layer context for mTLS.
- observability-stack — auditing, tracing identity propagation.
- identity-auth-policy — language- and ecosystem-specific identity libraries and policy DSLs.
22. Citations
- Hardt, D. (ed.) RFC 6749 — The OAuth 2.0 Authorization Framework. IETF, 2012.
- Sakimura, N.; Bradley, J.; Jones, M.; de Medeiros, B.; Mortimore, C. OpenID Connect Core 1.0. OpenID Foundation, 2014.
- OASIS. Assertions and Protocols for the OASIS Security Assertion Markup Language (SAML) V2.0. OASIS Standard, March 2005.
- Pang, R.; Caceres, R.; Burrows, M.; Chen, Z.; Dave, P.; Germer, N.; Golynski, A.; Graney, K.; Kang, N.; Kissner, L.; Korn, J.; Parmar, A.; Richards, C.; Wang, M. “Zanzibar: Google’s Consistent, Global Authorization System.” USENIX ATC, 2019.
- W3C. Web Authentication: An API for accessing Public Key Credentials, Level 3. W3C Recommendation, 2023.
- FIDO Alliance. Client to Authenticator Protocol (CTAP) 2.1 / 2.2; FIDO2 Server Requirements and Transport Binding Profiles; Multi-Device Credentials (Passkeys) Specification, 2019–2024.
- NIST. SP 800-63-4 Digital Identity Guidelines (Draft), 2024.
- NIST. SP 800-207 Zero Trust Architecture, 2020.
- Ward, R.; Beyer, B. “BeyondCorp: A New Approach to Enterprise Security.” USENIX ;login: 39(6), 2014.
- Osborn, B.; McWilliams, J.; Beyer, B.; Saltonstall, M. “BeyondCorp: Design to Deployment at Google.” USENIX ;login: 41(1), 2016.
- Birgisson, A.; Politz, J. G.; Erlingsson, Ú.; Taly, A.; Vrable, M.; Lentczner, M. “Macaroons: Cookies with Contextual Caveats for Decentralized Authorization in the Cloud.” NDSS, 2014.
- Jones, M.; Bradley, J.; Sakimura, N. RFC 7519 — JSON Web Token (JWT). IETF, 2015.
- Fett, D.; Bradley, J.; Hardt, D.; Lodderstedt, T. RFC 9449 — OAuth 2.0 Demonstrating Proof of Possession (DPoP). IETF, 2023.
- Sakimura, N.; Bradley, J.; Jones, M. RFC 9126 — OAuth 2.0 Pushed Authorization Requests. IETF, 2021.
- Lodderstedt, T.; Bradley, J.; Labunets, A.; Fett, D. RFC 9396 — OAuth 2.0 Rich Authorization Requests. IETF, 2023.
- Hughes, P.; Cantor, S.; Hodges, J.; Hirsch, F.; Mishra, P.; Philpott, R.; Maler, E. SAML 2.0 Core, Bindings, Profiles, Metadata. OASIS, 2005.
- Hunt, P.; Grizzle, K.; Wahlstroem, E.; Mortimore, C. RFC 7644 — SCIM: Protocol. IETF, 2015.
- Biggs, A.; Sondhi, S.; Saxe, E. RFC 7643 — SCIM: Core Schema. IETF, 2015.