October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk5 min

A Client-Supplied Tenant ID Is Not Authorization: How to Enforce Tenant Isolation Correctly

A tenant ID sent by the client only requests a context. Here is how to verify membership, scope every lookup, cover caches, storage and async jobs, and test for cross-tenant access.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A tenant ID that arrives in a header, query string, URL path or request body is a request: “I would like to act in tenant X.” It does not show that the caller is allowed to. If your server reads that value and uses it to pick data, you have a selector with no check behind it, and any signed-in user can try other tenants’ values.

OWASP’s Multi-Tenant Security Cheat Sheet puts it this way: “Treat client-supplied tenant identifiers as selectors only. Verify that the authenticated principal is authorized to act in the selected tenant.” This article covers what that check looks like, where it must be enforced, how to compare isolation designs, and how to test it.

As an Amazon Associate I earn from qualifying purchases.

Why a valid login and a valid tenant ID still aren’t enough

Two separate questions must both be answered on every request, and a client-supplied tenant ID answers neither:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • Is this principal entitled to act in this tenant right now? This is current membership, or authorization for a service account.
  • Is this principal allowed to perform this operation on this specific resource? This is object-level authorization.

Authentication only proves who the caller is. OWASP’s IDOR guidance and Authorization Cheat Sheet both stress that each request touching an object needs a permission check for that object and that operation. Checking only an identifier or the object’s type can expose another tenant’s records.

The attack in one example

A user in tenant acme calls GET /api/invoices/8841 with the header X-Tenant-Id: acme. They change the header to globex, or change the invoice number. If the handler runs SELECT * FROM invoices WHERE id = 8841, or trusts the header for scoping, the response may contain another tenant’s invoice. This is a classic Insecure Direct Object Reference (IDOR), applied across tenant boundaries.

Random IDs are not a fix

Opaque identifiers such as UUIDs make enumeration harder. OWASP is explicit that they are not an authorization control. An ID that leaks through a log, a shared link, an email or a support ticket still works if the permission check is missing.

The correct flow

  1. Establish identity on the server. Derive the principal from a verified session or token, not from request fields.
  2. Resolve the tenant context the principal may use. Look up their current membership (or, for services, their authorization). If a user belongs to several tenants, the client’s value can only request a switch. The server confirms the switch is permitted.
  3. Bind that verified context to the request. Downstream components should receive the server-verified context and must not be able to override it with unverified input.
  4. Authorize the action on the resource. Check that the principal may perform this operation on this object within this tenant.

A client-sent tenant value can legitimately be compared with the trusted context, and rejected if they differ. It must never be the thing that creates the context.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Scope every lookup to the tenant

For tenant-owned objects, the lookup or policy must include both the object and the authorized tenant context. An unscoped fetch by resource ID is unsafe whenever it can return an object owned by another tenant. Illustratively:

  • Unsafe: find(invoice_id), then hope a later check catches a mismatch.
  • Safer: find(invoice_id, tenant = ctx.tenant), where ctx.tenant comes from the verified request context, followed by a check of the specific operation.

Enforce this at a boundary that every tenant-owned access path crosses, such as a tenant-scoped repository layer or a central policy point. Scattering ad hoc checks across handlers leaves gaps. Data-layer safeguards add defense in depth by limiting the damage when application code forgets a check.

Don’t stop at the route handler

Tenant isolation fails at the paths people forget. Review each of these:

Alternate routes and internal calls

Older API versions, bulk endpoints, export and administrative actions, and service-to-service calls often reach the same data without the same checks. Internal callers should pass the verified context, not a raw tenant ID.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Caches

A cache key that omits tenant scope can serve one tenant’s value to another. Include tenant scope in the key, and authorize before serving a protected cached value.

Files, object storage and signed URLs

Storage paths and filenames are caller-controlled references too. Issue a signed URL only after authorizing the exact object and operation. Once issued, the URL carries the access.

Asynchronous jobs

A tenant ID inside a queued message is not proof that the producer was authorized or that the consumer should trust it. Re-establish authorization at the consumer.

Choosing an isolation mechanism

OWASP does not name one architecture as universally correct. It presents database and infrastructure isolation as design choices and recommends enforceable controls suited to the risk. The options are:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Option What enforces the boundary If app code omits a check
Application policy only Checks in code Largest exposure; nothing else stops the query
Tenant-scoped repository or query layer Shared data-access code adds tenant scope Protected on paths that use the layer; raw queries bypass it
Database row-level security (RLS) Database policies on shared tables Database still filters rows, if context is set correctly
Schema or credential separation Per-tenant schema or database credentials Limited by what the credentials can reach
Physical separation Separate infrastructure per tenant Smallest blast radius; highest operational cost

Compare them on five axes: strength of the enforceable boundary, coverage of every data access path, blast radius when a check is missed, operational complexity (including safe context handling under connection pooling and async work), and fit to the data’s sensitivity and your threat model.

If you use PostgreSQL row-level security

RLS is an implementation option for shared tables, not a requirement. OWASP calls out two cautions:

  • Request-time database roles must not bypass RLS.
  • Tenant context must be set carefully per transaction, especially with pooled connections, so one request’s tenant setting never carries over to the next.

Also inventory every tenant-owned table so none is left without a policy.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

How to test it

  1. Create at least two principals in different tenants, each with their own resources.
  2. Authenticate as one and substitute the other’s tenant value or object reference.
  3. Try every operation that applies: read, create, update, delete, export and administrative actions. All should be denied.
  4. Vary where the reference sits: path segments, query strings, bodies and filenames.
  5. Hit alternate endpoints and data paths, not only the primary route.
  6. Test pooling if you use RLS tenant settings: confirm context doesn’t leak between requests on a reused connection.
  7. Repeat after changes to caching, queries, service boundaries or shared resource handling.

Tests must pass even when IDs are unguessable. A test that only tries sequential numbers will wrongly pass an opaque-ID system that has no real check.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Review checklist

  • Tenant context comes from verified identity and current membership, never directly from a request field.
  • Tenant-switch requests are validated against membership.
  • Every tenant-owned lookup carries tenant scope and an operation-level check.
  • Cache keys include tenant scope.
  • Signed URLs are issued only after authorizing the specific object and operation.
  • Queue consumers re-authorize rather than trusting message contents.
  • Exports, admin tools and internal services follow the same rules.
  • Cross-tenant tests exist for each operation and run on changes.

The guidance here draws on OWASP’s Multi-Tenant Security, IDOR Prevention, Authorization and Authorization Patterns cheat sheets, and its Web Security Testing Guide chapter on insecure direct object references. Those sources describe the mechanism and controls but do not publish a prevalence figure for this class of flaw, so none is claimed here.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.