3.3 Authorization Models: RBAC, ABAC, ReBAC, and Resource-Level Checks
The authentication and authorization entities determine what actions the current context subject can perform on specific resources. Many privilege escalation vulnerabilities aren't due to lack of login, they arise when applications only check "logged in" or "has a certain role," without verifying the relationship between the target resource and the subject.
A single decision requires at least four inputs
allow? = policy(subject, action, resource, context)- subject: Users, services, devices, and their organizations, roles, and authentication guarantees;
- action: read, update, approve, transfer, rather than HTTP methods alone;
- resource: specific orders, projects, fields, tenants, and current status;
- context: time, network, device risks, change windows, and request origin.
Security defaults to deny. High-risk operations should never be silently permitted when there's no matching allow rule, missing policy data, policy engine timeout, or uncertain identity.
RBAC Manages Stable Job Responsibilities
user → role → permissionsRBAC is suitable for stable responsibilities like "auditors can read reports" and "release managers can approve releases." Roles should reflect business responsibilities, not create a role for each page. If combinations like admin-east-read-except-finance-temp explode, it indicates that additional attributes or relationships are needed.
Don't write admin as a boolean value that bypasses all authorization. High-privilege operations should also have clear actions, scopes, re-authentication, and auditing, and allow separation between regular accounts and temporary privilege sessions.
ABAC Using Attributes to Express Dynamic Constraints
ABAC can be combined:
subject.department == resource.department
AND resource.classification <= subject.clearance
AND context.time within approved_window2
3
It's expressive, but the claims themselves need trustworthy sources, types, timeliness, and ownership. If users can modify their own department claims, no strategy can be meaningful. The policy language should include testing, change reviews, and explainable decision logs to avoid scattered conditional branches across dozens of controllers.
Description of the Subject-Object Relationship in ReBAC
Collaborative documents, code repositories, and social products often rely on relationships:
user:lin is member of team:atlas
team:atlas is editor of project:north
therefore user:lin can edit document:x in project:north2
3
ReBAC can express inheritance, sharing, and organizational hierarchies, but it requires control over traversal depth, cycles, cache consistency, and delayed relationship revocation. Simply replacing object IDs from 17 with UUIDs only reduces enumeration convenience and cannot substitute for relationship checks on every resource access.
IDOR/BOLA from Missing Resource-Level Authorization
Dangerous process:
GET /orders/8172
→ Verify that the user is logged in
→ SELECT * FROM orders WHERE id = 8172
→ Return2
3
4
Security queries should incorporate authorization scopes early in the data access process:
SELECT ...
FROM orders
WHERE id = :order_id
AND tenant_id = :principal_tenant
AND owner_id = :principal_id;2
3
4
5
More complex permissions can first be determined by the policy engine to define allowed scopes or relationships, then queried against objects. Regardless of the architecture used, list, detail, update, export, batch interfaces, and background tasks must all perform consistent checks. Hiding buttons on the frontend offers no security value.
Tenant boundaries should span the entire chain of custody
The tenant should not be derived solely from the client header. The tenant must be determined from authenticated identity and server-side routing context, and this tenant identifier must be propagated across database queries, cache keys, object storage paths, queue messages, search indexes, and log access.
If caching relies solely on resource_id, it might return Tenant A's objects to Tenant B; if backend workers trust the tenant in the message without verifying the task initiator, they could execute across boundaries. Tenant isolation is a property of the data model and execution context, not a filter in the API gateway.
Confused Deputy: A service with privileges is misused to do harm
A transformation service has the privilege to read all objects, and if a user submits any source_url for it to read internal management addresses, this service becomes a confused deputy. Mitigations include:
- Represents the user calling downstream by passing or exchanging a restricted delegated credential;
- Bind audience, resource, action, and tenant to the token;
- The service's own permissions intersected with the user's permissions;
- Does not accept arbitrary resource references; uses server-side parsing and an allowlist;
- Retain the original principal chain and auditing for cross-boundary operations.
Centralized policy does not require a single remote call
We can centralize strategy definitions in a versioned policy repository and choose among sidecar, embedded evaluator, or local caching based on latency and availability. Must be clear that:
- When the policy decision point is unavailable, which actions fail closed;
- How long does policy and relationship data propagate, and what is the revocation window?
- Does the cache key include subject, resource, action, tenant, and policy version?
- Does the decision log record input summaries, rule versions, and results, while avoiding disclosure of sensitive information;
- Does emergency deny have a distribution path faster than a regular release?
High-risk actions can use just-in-time elevation with temporary, resource-limited access, approval, and automatic expiration. Permanent superadmin privileges expand the attack surface and make routine operations harder to distinguish from emergencies during an audit.
Authorization Test Matrix
Positive: The correct subject can perform the allowed action
Horizontal: Users with the same role cannot access other users' resources
Vertical: Regular users cannot perform high-privilege actions
Cross-tenant: No resource references are allowed to cross tenant boundaries
Status: Closed/Frozen: object refuses an action that was previously allowed
Revocation: After a relationship or role is terminated, it takes effect within the agreed-upon window.
Fault: Fails as designed when the policy service/attribute source is unavailable
Batch: Lists, exports, and async tasks behave consistently with single-object checks2
3
4
5
6
7
8
No matter how strong the authentication, it won't automatically grant correct authorization. The true backbone of a permission system lies in placing resource-level checks within the server's trusted boundary and making policies testable, explainable, and revocable.
References
- NIST, Guide to Attribute Based Access Control
- OWASP, Authorization Cheat Sheet
- OWASP API Security, Broken Object Level Authorization