API authorization security is the set of controls that decide what a verified caller can actually do, which records, which fields, which actions once identity is no longer in question. Authentication settles who someone is; authorization settles what happens next. Because that decision has to be made fresh on every single request rather than once at login, it tends to be where API security programs are weakest, and where breaches most often actually originate.
Where Authorization Actually Lives
A useful way to think about authorization isn’t as one check, but as a decision made at up to three different layers, each of which can silently fail on its own:
- The gateway/edge layer coarse-grained checks like "does this client have a valid scope for this route at all?" Fast, but it can't know whether the specific record being requested belongs to the caller.
- The service layer business logic that's supposed to verify the caller against the specific resource ("does this order belong to this user?"). This is where most authorization actually needs to happen, and where it's most often skipped because it requires a deliberate line of code on every handler, not a config setting.
- The data layer row-level security or query-scoping is enforced at the database itself, acting as a backstop if the service layer forgets. Underused, but it's the only layer that fails safely if a developer makes a mistake upstream.
Most breaches trace back to teams relying entirely on the first layer and assuming it covers the second a gateway confirming “this token is valid for /orders” says nothing about whether the token’s owner should see order #4471.
Authorization Models, and Why the Choice Matters
- Role-Based Access Control (RBAC) ties permissions to a role admin, editor, viewer and works well for coarse, functional gating. It breaks down in multi-tenant products, where "editor" needs to mean something different per customer account.
- Attribute-Based Access Control (ABAC) evaluates rules against attributes of the user, resource, and context department, data sensitivity, time of day allowing finer policy than a role name alone can express.
- Relationship-Based Access Control (ReBAC) grounds the decision in an explicit relationship graph: this user belongs to this team, this document belongs to this account. It's the model that maps most naturally onto multi-tenant SaaS, and it's what Zanzibar-style systems and open-source equivalents like OpenFGA were built around.
- Policy-as-code engines (Open Policy Agent is the common example) externalize authorization logic out of application code, so a policy change doesn't require redeploying every service enforcing it, and the policy can be tested independently of the code that calls it.
These aren’t mutually exclusive mature systems often pair RBAC for functional gating with a relationship or attribute check underneath for the actual record-level decision.
Where Authorization Design Quietly Fails
- Tenant boundary leakage. In multi-tenant systems, the most damaging failures aren't 'user A sees user B's record' but 'customer A's data leaks into customer B's account' a far larger blast radius, usually caused by a missing tenant-ID filter on a shared query path. (This is the failure mode OWASP's API Security Top 10 ranks as the #1 API risk: Broken Object Level Authorization, or BOLA.)
- Token claims trusted without re-verification. A JWT might carry a role or tenant ID as a claim, but if it was set at login and never re-checked, a demoted or offboarded user can keep acting on stale permissions until the token expires.
- Authorization logic duplicated across services. When each microservice reimplements its own permission checks instead of calling a shared policy layer, they drift apart over time the inconsistency itself becomes the vulnerability.
- Bulk and export endpoints treated like single-record endpoints. A check that works for "get my invoice" doesn't automatically scale to "export all invoices" ; ownership logic has to be re-applied per row, not just per request.
Practical Authorization Guardrails
- Push authorization down to the resource, not just the route. A route-level scope check is necessary but never sufficient on its own.
- Treat token claims as a hint, not a source of truth for anything sensitive,re-check current permission state for high-impact actions rather than trusting what was true at login.
- Centralize policy logic rather than letting every service reimplement its own version of "does this user own this," so a fix in one place fixes it everywhere.
- Applying the same ownership check to bulk operations as single-record ones exports, batch updates, and admin tooling are common places where the check gets forgotten.
- Instrument denials, not just approvals. A cluster of 403s from one account is often the earliest visible sign that someone is probing for a gap.
The Takeaway
Authentication is a gate you pass once; authorization is a judgment call an API has to make correctly on every request, for every object, indefinitely. That repetition is exactly what makes it hard to get right consistently and exactly why the choice of model, and where enforcement actually lives in the stack, matters more for authorization than for almost any other API security control.
APIs Under Attack, Prophaze Secures Every Call
Discover every API, block zero‑day attacks and bots, and enforce policies at scale—without slowing your developers down.