Server Responsibilities · 2 of 6

Authorization

Once you know who the user is, decide what they're allowed to do. The most-broken layer in most apps — and the one with the highest blast radius when it fails.

RBACABACReBACPoliciesOPACedarOAuth Scopes
← Back to Server Side
Quick Facts

At a Glance

Basic Concepts

  • Subject: the actor — usually a user, sometimes a service.
  • Action: what they're trying to do (read, delete, refund).
  • Resource: what they're trying to do it to (a document, an order, a tenant).
  • Policy: the rule that says "yes" or "no" given subject + action + resource + context.
  • Enforcement point: where the policy actually runs — middleware, controller, service, or DB row filter.
Models

The Core Authorization Models

RBAC — Role-Based Access Control

Users are assigned roles (admin, editor, viewer); roles have permissions. Simple, well-understood, and the right starting point for most apps.

Breaks down when permissions need to depend on which resource — "editor of Project A but viewer of Project B." That's where you graduate to ABAC or ReBAC.

ABAC — Attribute-Based Access Control

Decisions consider attributes of the subject, resource, action, and environment: user.department == doc.department AND time < 18:00. Expressive but easy to make incomprehensible. Pairs well with a policy engine.

ReBAC — Relationship-Based Access Control

Permissions follow graph relationships: "user is a member of org that owns folder that contains this doc." Pioneered by Google's Zanzibar; productized by SpiceDB, OpenFGA, Permify, Warrant. The right tool when sharing & nesting are first-class.

Policy-as-Code Engines
  • Open Policy Agent (OPA) / Rego — CNCF standard; widely used for Kubernetes and microservice authorization.
  • Cedar — AWS's open-source policy language behind Verified Permissions; designed for end-user app authorization.
  • Casbin — embeddable library with multiple model templates (RBAC, ABAC, ACL).
OAuth Scopes vs App Permissions

OAuth scopes describe what an API client is allowed to ask for (read:invoices). App-level permissions describe what the user behind that token is allowed to do. You need both: a scope-limited token from a billing assistant should never escalate beyond what the human user already has.

Multi-Tenancy

Tenant Isolation

The single most common authorization bug in B2B SaaS: leaking data across tenants because a query forgot the tenant_id filter. Mitigations:

  • Postgres Row-Level Security (RLS) — enforces the tenant filter at the database, not in app code.
  • Schema-per-tenant or DB-per-tenant — strongest isolation, highest operational cost.
  • Scoped repositories — every data-access object requires tenant context to construct.
Enforcement

Where to Check

LayerWhat it catchesWhat it misses
API Gateway / MiddlewareCoarse rules: "must be logged in," "must have admin scope."Per-resource ownership ("is this your invoice?").
Controller / HandlerAction-level checks before business logic runs.Bulk operations that touch many resources.
Service / DomainInvariants like "only the assignee can close this ticket."Read paths if you check only on writes.
Database (RLS, views)The catch-all — even buggy queries can't escape.Performance overhead; harder to debug.

Defense in depth: enforce at multiple layers. A bug at one layer shouldn't be a breach.

Pitfalls

Common Mistakes

  • IDOR (Insecure Direct Object Reference)GET /invoices/42 works for any user who guesses the ID. Always check ownership, not just authentication.
  • Forgetting the negative case in listsGET /invoices happily returns every invoice in the table because the WHERE clause was dropped.
  • Client-side hiding — graying out a button is UX, not security. Re-check on the server.
  • "Admin" as a single bit — eventually you need finer roles, and refactoring a boolean into an RBAC system mid-flight is painful.
  • Stale role caches — when admin access is revoked, the user's existing JWT may still grant it for an hour. Plan for revocation.
  • Confused deputy — a service acting "on behalf of" a user but with its own elevated rights. Pass the user's identity through, don't impersonate.
Continue

Other Server Responsibilities