Back to the map

Module 04 · API fundamentals · Lesson 11 of 15

Authentication vs authorization

Who are you, and what are you allowed to do: two different questions answered at two different points in the request path. Where each check lives in a system, the models for expressing permissions, and the mistakes that leak data.

IntroMust-knowJunior 8 min Updated Nov 2026

Why it matters

Most data leaks are not broken encryption; they are an endpoint that checked who you were and forgot to check whether you were allowed to see that particular record. Separating authentication from authorization, and knowing where each belongs in the request path, is the foundation every API security lesson in this module builds on.

The idea

Authentication (authn) establishes identity: this request comes from user 42, or from service billing. Authorization (authz) decides permission: user 42 may read order 9001 because they placed it, and may not read order 9002 because someone else did. Authentication happens once per request at the edge; authorization happens at every point where a decision depends on who is asking, which is usually deep in the service, next to the data.

ClientcredentialtokenGatewayauthn: who is this?principal: user 42Order serviceauthz: may 42 read 9001?authn once at the edge · authz at every data access
Authentication resolves credentials to a principal at the edge. Authorization checks that principal against each resource where the data lives.

How identity is established

Credentials come in a few forms: something the user knows (password), has (device, hardware key, one-time code) or is (biometric). For APIs, the credential is usually a token issued after one of those checks: a session id, a signed JWT, an API key for a program, or a certificate for service-to-service calls (mutual TLS). The lessons that follow cover sessions, tokens, JWTs and the OAuth flows that issue them. Whatever the mechanism, the output is a principal: a trusted identity plus attributes (roles, tenant, scopes) attached to the request for the rest of its journey.

How permission is expressed

ModelRule shapeFits
RBAC (role-based)Users have roles; roles have permissions: 'admins can delete orders'Most applications; simple, auditable
ABAC (attribute-based)Policies over attributes of user, resource and context: 'owner may edit while status is draft and it is business hours'Fine-grained rules, multi-tenant, regulatory
ReBAC (relationship-based)Permissions derived from a graph of relationships: 'viewers of a folder can view its documents'Sharing-heavy products (docs, drives); Google Zanzibar style
ACLsPer-resource list of who can do whatSmall sets of resources; becomes unmanageable at scale

Most systems start with RBAC for coarse permissions and add ownership checks (ABAC in miniature) for records: "role allows reading orders, and this order belongs to this user's tenant". Centralising the decision in one policy module or service keeps rules consistent and testable instead of scattered across handlers.

The classic mistakes

  • Checking authn and skipping authz: any logged-in user can fetch /orders/9002 by changing the id. Called broken object-level authorization, it tops every API vulnerability list.
  • Authorizing in the client: hiding a button is not a permission check. The API must enforce it.
  • Trusting forwarded identity without verification: internal services accepting a X-User-Id header from anyone on the network. Verify the token or use a mesh that does.
  • Overbroad principals: one API key with every scope, shared by three teams. Least privilege: issue narrow scopes and rotate keys.

Trade-offs

Checking authorization at the edge is fast and simple and can only enforce coarse rules, because the edge does not know who owns order 9001. Checking next to the data is precise and must be done consistently in every handler. A central policy service gives consistency and adds a dependency on the hot path, usually mitigated with a local cache or sidecar.

In an interview

Say both words and where each lives: "The gateway authenticates the token and attaches the principal; each service authorizes against the resource, so reading an order checks that the order's tenant matches the caller's." Then name the model: "RBAC for admin versus user, plus ownership checks per record." Mention least privilege for service accounts if the design has internal calls.

Check yourself

A logged-in user changes the id in /api/invoices/1001 to 1002 and sees another customer's invoice. Which check was missing?

Authentication vs authorization · Backplane