Reqflow
← All concepts
Security·3 min read

Authentication vs Authorization

Authentication proves who you are; authorization decides what you're allowed to do. Different problems, often confused.

Try it

Sign in as a role (authentication), then try an action (authorization).

Authenticated as

Authentication answers "who are you?" (login, tokens). Authorizationanswers "what are you allowed to do?" (roles, permissions). You can be perfectly authenticated and still get a 403 because you are not authorized for that specific action.

First time reading this? Start here

Plain English: authentication (authn) is logging in, proving you are who you say you are. Authorization (authz) is checking whether you're allowed to do a specific thing once you're logged in. Being authenticated doesn't mean you're authorized; they're two separate checks.

What it is

Two distinct security steps. Authentication (AuthN) verifies identity, confirming the caller is who they claim to be, via passwords, tokens, certificates, or biometrics. Authorization (AuthZ) verifies permission: given a known identity, deciding whether they may perform a specific action on a specific resource, via roles (RBAC), attributes (ABAC), or policies.

The problem it solves

Systems need to both establish identity and enforce boundaries. Authentication answers 'who are you?', and without it, anyone is anonymous. Authorization answers 'are you allowed to do this?', and without it, any authenticated user could do anything. Separating them keeps each concern clean: you authenticate once and authorize on every sensitive action.

How it works

AuthN: the user presents credentials; the system verifies them and issues a token (a signed JWT, or an opaque session id stored server-side). Standards like OAuth2 (delegated access) and OIDC (identity on top of OAuth2) handle this for third parties. AuthZ: on each request, the system reads the identity from the token and checks it against a policy: RBAC maps users to roles to permissions; ABAC evaluates attributes (department, resource owner, time); policy engines (OPA) externalize the rules. The gateway or service enforces the decision before doing the work.

Why use it

  • Separating identity from permission keeps each concern clean and independently testable
  • Standards (OAuth2/OIDC, JWT) mean you rarely build authentication from scratch
  • RBAC/ABAC let permission rules evolve without touching authentication

What it costs you

  • JWTs are hard to revoke before expiry: a stolen token is valid until it expires unless you add a denylist
  • Authorization logic sprawls: scattered ad-hoc checks across services drift and create security holes
  • OAuth2/OIDC are notoriously easy to misconfigure (redirect URIs, scopes, token validation) into vulnerabilities

Where it shows up in our architectures

  • Payment Gateway

    API-key authentication identifies the merchant; authorization scopes restrict which operations and accounts that key may touch

  • URL Shortener

    The API gateway authenticates the JWT and authorizes whether the user may create or manage a given short link

  • Google Docs (Realtime Collab)

    Authentication identifies the editor; per-document authorization (owner/editor/viewer) decides who can read vs write each doc

Gotchas

  • AuthN and AuthZ are not the same check. 'You're logged in' never implies 'you may do this'; a valid token still has to pass an authorization check on the specific resource.
  • Stateless JWTs trade revocability for scalability: you can't easily kill one mid-life. Use short expiries plus refresh tokens, or keep a revocation list, for anything sensitive.
  • Centralize authorization. Ad-hoc 'if user.role == admin' checks copied across services inevitably drift, so push the decision to a gateway or a policy engine (OPA) with one source of truth.
  • Always validate token signature, issuer, audience, and expiry on every request. Skipping any of these is the classic JWT vulnerability; trusting an unvalidated token is no security at all.
When this went wrong in production

Heroku's OAuth token breach: 7-week secret exposure · 2022

Postmortem ↗

An attacker stole Heroku's GitHub OAuth tokens and downloaded private repos for 7 weeks undetected.

In April 2022, GitHub notified Heroku that OAuth tokens from Heroku's GitHub integration had been used to access private repositories, including Salesforce's own internal infrastructure repos. The attacker got the tokens from an internal Heroku database. They'd been stored with insufficient encryption and the attacker had access for roughly 7 weeks before detection. Because the access pattern (a token reading repos it had authorized access to) looked like normal OAuth usage, existing monitoring never flagged it. Heroku revoked all OAuth tokens, breaking GitHub integrations for every Heroku customer. The lesson: OAuth tokens at rest are secrets. Encrypt them with envelope encryption and rotate them. Anomaly detection for authorization must use behavioral baselines, not just permission checks.

Azure Active Directory outage: MFA breaks for 14 hours · 2023

Postmortem ↗

A corrupted database update took down Azure AD MFA globally, locking millions of users out of Microsoft services.

In September 2023, a routine Azure Active Directory update introduced a corrupted data entry into the authentication service's configuration store. That store is read on every MFA request, so within minutes of deployment, MFA was failing globally. Services that depend on Azure AD for login, including Microsoft 365, Teams, Azure Portal, and Xbox, all started rejecting multi-factor auth. Because MFA was broken, engineers trying to reach the management plane to roll back had to use break-glass procedures. The update was eventually rolled back, but re-validation and cache clearing across global infrastructure took 14 hours. The lesson: configuration stores are critical path for every request. Changes to them must be validated on live traffic via canary before global rollout. Break-glass procedures must not depend on the service they're trying to fix.

Interview angle

Auth questions test whether you know authn and authz are two different steps. The mistake to avoid is conflating them: being authenticated does not mean being authorized, and a valid JWT still needs a permission check on every sensitive action. Show you know the JWT revocation problem (short expiry plus refresh tokens, or a denylist), and mention that authorization logic should be centralized in a policy engine or gateway rather than copy-pasted across services. Candidates who say 'check if the user is logged in' for authorization questions show they've only thought about login, not access control.

Your notes

Private to you