DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsSlow PC?RecommendedPC slow today? Run a repair scan before it gets worseResolve common Windows issues and optimize system performance.Scan Now×
Skip to content
World desk5 min

Never Trust a Client-Supplied Tenant ID: Verify Tenant Access on the Server

A tenant ID sent by the client says where the caller wants to work, not where they're allowed to. Here is how to verify and enforce tenant access on the server.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A tenant ID that arrives in a header, URL path, query string or request body is only the tenant the caller asks to work in. It does not show that the caller is allowed to. The server has to check that the authenticated principal may act in that tenant, and then enforce that scope on every backend operation that touches tenant data.

OWASP’s Multi-Tenant Application 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.”

As an Amazon Associate I earn from qualifying purchases.

Selector versus proof of authorization

A client often needs to say which organization, workspace or account it is working in. A user may belong to several, so accepting a tenant selector is a normal API design. The mistake is letting that selector also decide what the caller may see or change. Anything the client sends can be edited, replayed or forged, so it cannot carry authority on its own.

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

An illustrative example, not a reported incident: a user signed in to tenant 42 calls GET /api/invoices with the header X-Tenant-ID: 42. They change it to 43 and resend. If the server trusts the header and builds its query from it, it returns tenant 43’s invoices. The user was authenticated, but nothing checked that they belong to tenant 43. The same flaw appears when the ID sits in the path (/tenants/43/invoices), in a JSON body, or in an ID for a nested resource that belongs to another tenant.

#1 Best Overall

The request flow that keeps the selector honest

  1. Authenticate the caller. Establish who is making the request from a verified session or credential, not from anything in the request payload.
  2. Read the requested tenant as a claim to verify. Take the tenant ID from the header, path or parameter, and validate its format.
  3. Verify access to that tenant. Confirm the authenticated principal has an applicable, current membership or authorization for the selected tenant. Service accounts need an equivalent grant.
  4. Authorize the specific operation. Check the action, the resource and the tenant together. Being a member of the tenant does not mean every action on every resource is allowed.
  5. Only then read or change data, with the verified tenant scope applied to the query or operation.

If step 3 or 4 fails, stop before any tenant data is touched. Which HTTP status to return (for example 403 or 404, which can hide whether the tenant exists) depends on your API’s design and was not prescribed by the guidance used here.

Where the check has to live

On the backend path that reaches the data

OWASP’s Micro Frontend Security Cheat Sheet says backend requests must enforce permissions for the operation, the resource and the tenant, regardless of what the frontend does. Hiding a tenant switcher, disabling a button or keeping the tenant in client state is a usability feature. It is not an access control, because an attacker can call the API directly.

At a boundary every access path passes through

Put enforcement where all tenant-owned access paths converge, such as a shared authorization layer or data-access layer, rather than relying on each endpoint’s author to remember it. A check that exists in nine of ten handlers is the check an attacker will look for the tenth of. OWASP’s Authorization Patterns Cheat Sheet stresses that the policy decision must be enforced before the resource is accessed. Having a central policy engine does not remove the responsibility of the code that enforces its answer.

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.

Trusted headers added by a gateway

Some architectures have a gateway or middleware that resolves the tenant and passes it downstream in a header. That can be sound, but only if:

  • the gateway or component is authenticated by the services behind it, and cannot be bypassed by calling those services directly;
  • any client-supplied copy of that header is stripped or overwritten at the edge, which the OWASP Authorization Patterns guidance calls out;
  • downstream services still enforce authorization instead of assuming the header settles it.

Tenant claims in tokens

If your identity system issues a verified tenant claim, you can use it as the authoritative source instead of a request parameter. Confirm that the issuer and the claim’s semantics actually support that use (for example, whether it means “current active tenant” or “every tenant the user has ever joined”). Also apply any current membership or authorization checks your product’s rules require, because a token can outlive a removed membership.

What the standard asks for

OWASP’s Application Security Verification Standard 5.0.0, requirement V8.4.1, reads: “Verify that multi-tenant applications use cross-tenant controls to ensure consumer operations will never affect tenants with which they do not have permissions to interact.” Note the word operations: it covers writes, deletes and actions as well as reads. It also means a tenant-scoped list endpoint is not the only thing to review. Exports, background jobs, webhooks, search and file downloads are all places where a tenant can be supplied.

Review checklist

  • Does every endpoint that accepts a tenant ID verify the caller’s access to that tenant before using it?
  • Are object IDs checked against the verified tenant, so that a valid ID from another tenant is refused?
  • Is the tenant scope applied server-side to every query and mutation, not only to the ones the UI uses?
  • Are client-supplied copies of internal tenant headers removed at the edge?
  • Can internal services be reached directly, skipping the gateway that sets trusted context?
  • Is membership checked at request time, or only when a token was issued?
  • Do background jobs and async workers carry a verified tenant context, rather than reading one from a queued message that a user could influence?
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Testing that cross-tenant access is denied

Make cross-tenant denial a test, not an assumption. With two tenants and a user in each, check that:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  1. User A, authenticated, sends tenant B’s ID in each place the API accepts one (header, path, body) and is refused.
  2. User A requests tenant B’s resource IDs while naming tenant A as the tenant, and is refused.
  3. User A cannot perform write, delete and administrative actions in tenant B.
  4. A user removed from a tenant loses access, including with a token issued earlier, to the extent your design promises.

When you compare architectures such as shared tables with a tenant column, schema per tenant or database per tenant, judge them on four axes: how completely authorization is covered, how strong the isolation boundary is, how much operational complexity they add, and how easily cross-tenant denial can be tested. No single pattern is shown to be best in every case by the guidance used here. Specific database policies, token formats, middleware libraries and status codes depend on your platform, so use that platform’s own documentation before copying configuration.

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
Crashes, No Sound, or Screen Glitches?Free driver scan
Windows Errors? Fix Them Before They SpreadFree repair 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.