SaaS API BOLA prevention: object-level authorization checklist
Prevent broken object-level authorization in SaaS APIs by checking each record and action against the signed-in user, tenant policy and relationship on every request.
In this guide
What is broken object-level authorization (BOLA)?
Broken object-level authorization (BOLA) occurs when an API accepts an object identifier but fails to check that the signed-in user may perform the requested action on that specific record. A user who can call an endpoint may still be unauthorized to read, change or delete another tenant’s object. Check authorization on the server for every object access; random IDs, hidden interface controls and authentication alone are not access control.
Authorize the user, object and requested action together
For every request that reads or changes a record, evaluate the current identity, the object’s tenant or owner relationship, the requested operation and the product’s sharing rules. A check that only compares a user ID with an object ID is insufficient when teams, delegated roles or shared resources are involved. Use the same policy for API, web and background-job paths.
Scope database access to the authorized tenant or relationship
Derive tenant context from a trusted authenticated identity and query only records the person may access. Avoid loading a global object by client-supplied ID and assuming the interface already filtered it. Apply the policy to nested resources, bulk operations, GraphQL resolvers, exports, search results and asynchronous jobs.
Keep object access separate from property-level permissions
A person may be allowed to view a record but not change its owner, billing status, role or security settings. Validate which fields can be read or updated for each operation and reject unexpected fields. Object-level authorization and property-level authorization address different decisions and both may be necessary.
| Role / tenant relationship | Object type | Read / update / delete | Server-side policy | Cross-tenant test |
|---|---|---|---|---|
| Member | Report | |||
| Workspace owner | Member record | |||
| Support operator | Customer export |
How do SaaS teams enforce object-level authorization consistently?
Centralize policy decisions without trusting caller-supplied ownership
Use a clear authorization policy or domain service so controllers, resolvers and jobs apply consistent rules. Treat IDs, tenant names and ownership fields from the request body as untrusted; the server should derive or verify relationships from authoritative records. A policy should fail closed when identity or tenant context is missing.
Apply authorization to every method and collection path
Review GET, POST, PATCH, PUT, DELETE, bulk actions, list filters, nested routes and alternate API versions. A secure detail endpoint does not help if an export, search or batch job returns the same objects without its check. Ensure that denied requests do not partially update a record or reveal sensitive fields in an error.
Use unpredictable identifiers only as defense in depth
UUIDs or opaque IDs can make casual enumeration harder, but they do not establish permission. An ID can be copied from a notification, browser history, log, shared link or another API response. Keep the object-level authorization check even when identifiers are difficult to guess.
How do you test BOLA across SaaS tenants and roles?
Build a cross-tenant and role-based test matrix
Create at least two test tenants with separate users and records, plus roles such as member, owner and support staff where they exist. For each object type, exercise allowed and denied read, update, delete and bulk actions. Test shared records and delegated access separately from ordinary tenant ownership.
Test the API boundary with another user’s object identifier
In a controlled environment, authenticate as one test user and request an object owned by another test user. Confirm the server denies the operation without disclosing sensitive fields, even if the client changes a path, query, header or body identifier. Repeat for each endpoint and nested relationship that uses a client-provided ID.
Add regression tests and audit denied access patterns
Keep automated tests that prove a user cannot access another tenant’s records across APIs, jobs and exports. Log the principal, object type, operation, tenant context and decision safely; avoid logging sensitive record contents. Alert on repeated denied cross-tenant attempts and review policy changes before release.
SaaS BOLA prevention questions
Do UUIDs or hard-to-guess IDs prevent BOLA?
No. They can reduce casual enumeration but do not prove that the caller may access the record. Enforce authorization for the object and operation on every request.
Is authentication enough to protect an API object?
No. Authentication identifies the caller; authorization decides whether that caller may perform an action on a particular record. Check tenant membership, ownership, sharing and role policy at the server.
Is a tenant-ID comparison always sufficient?
Not by itself. Some records are shared, delegated or governed by role relationships, and a tenant value from the request may be forged. Derive context from trusted identity and evaluate the product’s actual access policy.
Does a secure web interface guarantee the API is safe?
No. Attackers and integrations can call APIs directly, and background jobs or exports may use different code paths. Enforce authorization on the server for every route, resolver, job and bulk operation.
Related practical guides
Related issue guides
Sources and publication record
Draft prepared 27 September 2026; engineering, security and editorial review pending · Sources checked .
- OWASP API Security Top 10: API1:2023 Broken Object Level AuthorizationOWASP Foundation
- OWASP Cheat Sheet: AuthorizationOWASP Foundation