Authentication & Authorization
Two words that sound similar and get confused constantly — and confusing them is how access-control bugs happen.
5.2.1Definition
Authentication (AuthN) verifies who a user is — typically via a password, one-time code, or federated identity provider. Authorization (AuthZ) determines what an authenticated user is permitted to do. A system can authenticate a user perfectly and still fail if it authorizes them incorrectly — these are separate concerns with separate failure modes.
5.2.2Why It Exists
Nearly every product beyond a static site (1.4) needs to know who is making a request and what they're allowed to do with it — without this, there is no way to protect user data, restrict paid features, or separate one customer's data from another's. Authentication and authorization together form the foundation every other security decision in this handbook builds on.
5.2.3Common Approaches
| Approach | How it works | Best fit |
|---|---|---|
| Session-based | Server stores session state; client holds a session cookie (5.3) | Traditional server-rendered apps |
| Token-based (JWT) | Client holds a signed, stateless token (5.3) | APIs, SPAs, mobile apps |
| OAuth 2.0 / OIDC | Delegated auth via a third-party identity provider | "Sign in with Google/GitHub" flows |
| Role-Based Access Control (RBAC) | Permissions attached to roles, roles attached to users | Enterprise apps (2.11), dashboards with staff roles (2.14) |
5.2.4Common Mistakes
- Authorizing on the client only. Hiding an admin button in the UI while the underlying API endpoint still accepts requests from any authenticated user — the actual vulnerability, not the missing button.
- Rolling a custom password-hashing scheme. Using a fast general-purpose hash (or worse, none) instead of a purpose-built algorithm like bcrypt or Argon2, which are deliberately slow to resist brute-forcing.
- Confusing "logged in" with "allowed." Checking only that a request has a valid session, without separately verifying that this specific user owns the specific resource being requested.
- Storing plaintext or reversibly-encrypted passwords instead of a proper one-way hash, turning any database breach into a full credential leak.
5.2.5Best Practices
- Enforce authorization on every server-side request, never trusting client-side UI state as a security boundary.
- Use an established identity library or provider rather than writing auth logic from scratch.
- Apply the principle of least privilege — grant only the permissions a role actually needs, checked at the resource level.