Authn vs Authz & Session-Based Auth
Authentication (authn) answers "who are you?" -- it verifies a claimed identity. Authorization (authz) answers "what are you allowed to do?" -- it enforces permissions after identity is established. Every secure system needs both, and they are separate concerns even when frameworks bundle them together.
| Aspect | Authentication | Authorization |
|---|---|---|
| Question | Who is this user? | What can they access? |
| When | Before authorization | After authentication |
| Mechanism | Passwords, tokens, biometrics | Roles, policies, ACLs |
| HTTP status on failure | 401 Unauthorized | 403 Forbidden |
Session-Based Authentication
The classic server-side pattern: after verifying credentials, the server creates a session object, stores it (in memory, Redis, or a database), and sends a Set-Cookie header with a random session ID. Every subsequent request includes this cookie, and the server looks up the session to identify the user.
SameSite cookies.
JSON Web Tokens (JWT)
A JWT is a compact, URL-safe token consisting of three Base64url-encoded parts separated by dots: header.payload.signature. The server does not need to store state -- it verifies the signature and reads claims directly from the token.
// Header
{ "alg": "RS256", "typ": "JWT" }
// Payload (claims)
{
"sub": "user_42",
"iss": "auth.example.com",
"exp": 1717200000,
"roles": ["admin"]
}
// Signature
RSASHA256(base64url(header) + "." + base64url(payload), privateKey)
Signing Algorithms
| Algorithm | Type | Key | Use Case |
|---|---|---|---|
HS256 | Symmetric (HMAC) | Shared secret | Single service, simple setups |
RS256 | Asymmetric (RSA) | Private signs, public verifies | Distributed systems, JWKS |
ES256 | Asymmetric (ECDSA) | Smaller keys, same security | Mobile, IoT, performance-sensitive |
Access + Refresh Tokens
A common pattern pairs a short-lived access token (5-15 min) with a longer-lived refresh token (days/weeks). When the access token expires, the client presents the refresh token to get a new pair. The refresh token is stored securely (httpOnly cookie or secure storage) and can be revoked server-side.
alg against a server-side allowlist; never trust the token header alone.
Token bloat -- every claim increases every request's size. Keep payloads lean.
OAuth 2.0
OAuth 2.0 is a delegation framework -- it lets a user grant a third-party app limited access to their resources on another service, without sharing their password. It defines several grant types for different scenarios.
Authorization Code + PKCE
The most common and secure flow for web and mobile apps. PKCE (Proof Key for Code Exchange) prevents authorization code interception attacks, which is why it is now required even for server-side apps in best-practice guidance.
Other Grant Types
Machine-to-machine auth. No user involved. The client authenticates with its own credentials and gets an access token directly. Used for backend services, cron jobs, microservice communication.
For input-constrained devices (smart TVs, CLI tools). The device shows a code, the user enters it on a browser. The device polls until the user completes authorization.
Scopes
Scopes limit what an access token can do. They are strings like read:user, write:repos, openid profile email. The authorization server includes granted scopes in the token response. Clients should always request the minimum scopes needed.
OpenID Connect & SAML 2.0
OpenID Connect (OIDC)
OIDC is a thin identity layer built on top of OAuth 2.0. It adds a standardized way to get user identity information. When you request the openid scope, the authorization server returns an ID Token (a JWT) alongside the access token.
| Component | Purpose |
|---|---|
| ID Token | JWT containing user identity claims (sub, email, name). Consumed by the client, never sent to APIs. |
| UserInfo Endpoint | GET /userinfo with access token. Returns additional claims about the authenticated user. |
| Discovery Document | GET /.well-known/openid-configuration returns all endpoints, supported scopes, algorithms, and keys (JWKS URI). |
SAML 2.0
Security Assertion Markup Language (SAML) is an older XML-based standard widely used in enterprise SSO. It involves two parties:
| Role | Description | Example |
|---|---|---|
| Identity Provider (IdP) | Authenticates the user and issues assertions | Okta, Azure AD, OneLogin |
| Service Provider (SP) | Relies on IdP assertions to grant access | Salesforce, Jira, internal apps |
A SAML Assertion is an XML document containing authentication statements (when/how the user authenticated), attribute statements (user metadata), and authorization decision statements. Assertions are digitally signed and often encrypted.
WebAuthn & FIDO2
WebAuthn (Web Authentication API) enables passwordless authentication using public-key cryptography. Together with CTAP (Client to Authenticator Protocol), it forms the FIDO2 standard. The private key never leaves the authenticator device -- the server only stores the public key.
Authenticator Types
Built into the device: Touch ID, Face ID, Windows Hello. Convenient for the user but tied to a specific device.
External hardware keys: YubiKey, Titan Key. Portable across devices, connected via USB, NFC, or Bluetooth.
API Security, Access Control & Password Hashing
API Authentication Methods
| Method | How It Works | Best For |
|---|---|---|
| API Keys | Static secret passed in header or query param | Identifying callers, rate limiting. Not true authn -- easily leaked. |
| mTLS | Both client and server present TLS certificates | Service-to-service in zero-trust networks. Strong identity but complex PKI. |
| HMAC Signing | Request body + timestamp signed with shared secret | Webhook verification, tamper-proof requests (e.g., AWS Signature V4). |
Rate Limiting
Essential for API security. Common algorithms include token bucket (smooth bursts), sliding window (precise counts), and leaky bucket (constant drain). Typically enforced per API key, per IP, or per user. Return 429 Too Many Requests with a Retry-After header.
RBAC vs ABAC
| Model | How Decisions Are Made | Trade-offs |
|---|---|---|
| RBAC (Role-Based) | User is assigned roles (admin, editor, viewer). Permissions are attached to roles. | Simple to reason about. Can lead to role explosion in complex systems. |
| ABAC (Attribute-Based) | Policies evaluate attributes of user, resource, action, and environment. | Fine-grained and flexible. More complex to implement and audit. |
Password Hashing
Never store passwords in plaintext or with fast hashes (MD5, SHA-256). Use purpose-built password hashing functions that are deliberately slow and memory-hard.
Adaptive cost factor, built-in salt, widely supported. Default cost 10-12. Battle-tested since 1999.
Winner of the 2015 Password Hashing Competition. Configurable time, memory, and parallelism. Argon2id variant recommended (resists both side-channel and GPU attacks).
Memory-hard function. Good alternative when Argon2 is unavailable. Used in some cryptocurrency proof-of-work schemes.