Skip to main content
Intelliger
MCP security and authority

MCP Tenant Isolation: A Negative-Test Matrix

Test MCP tenant isolation across tool arguments, caches, sessions, credentials, queues and evidence exports with paired synthetic fixtures.

Three separate architectural compartments with an orange test marker
Intelliger•

MCP multi-tenant isolation tests should prove that an authenticated caller cannot use another tenant's objects, credentials, caches, sessions or queued work. Testing only the visible search results misses many boundaries. Follow the request through the gateway, connector and evidence store, then deliberately substitute tenant context at each point where the system could trust the wrong source.

This matrix is for teams serving multiple organisations or isolated business units through a shared MCP deployment. All examples use synthetic tenants A and B with separate owners and test records. Run them only in an environment authorised for testing. The method evaluates your deployment boundaries; it is not a certification of MCP itself.

Define the trusted source of tenant context

Tenant context should come from a verified identity and an authorised relationship, not an arbitrary argument supplied by the model. Some systems allow an administrator to select a tenant, but that selection must be checked against current permissions. A tenant identifier in a URL, prompt or request body is an input to validate, not evidence of access.

MCP’s authorisation specification defines HTTP authorisation requirements including intended-resource validation. Audience validation does not replace your application's tenant and object checks. Two tenants may use the same resource server while remaining forbidden from accessing one another's records. Establish both boundaries explicitly in the integration design.

Build paired fixtures before writing assertions

Create the same object identifier in both tenants with visibly different synthetic content. This catches storage or cache keys that accidentally omit tenant context. Also create an identifier that exists only in tenant B. The response to tenant A should follow the agreed non-disclosure behavior without returning B's data or exposing unnecessary existence information.

Use separate connector credentials and evidence destinations for the fixtures. Record which credential the connector actually selects, without logging the secret. A passing application response is insufficient if the upstream call used a broadly privileged credential and fetched the wrong data before filtering it away.

BoundaryNegative testExpected observation
Tool argumentsTenant A submits tenant B's object referenceNo unauthorised data or side effect reaches the caller
CacheBoth tenants request the same local identifierEach receives only its own authorised record
SessionReuse a session reference under another identitySession ownership is checked before work resumes
ConnectorSubstitute a tenant selector before credential lookupCredential choice remains bound to verified context
QueueReplay an old job after reassignment or permission removalExecution rechecks current authority before dispatch
Evidence exportRequest another tenant's receipt bundleAccess is denied without exposing protected payloads

This table is a minimum starting set, not an exhaustive threat model. Add boundaries introduced by your deployment, including object storage, vector indexes, search filters, tracing tools, support consoles and backups. Each extra route to the data needs an owner who can explain how tenant context is enforced there.

Test caches and retrieval separately

Prime the cache with tenant B's result, then request the same identifier as tenant A. Repeat in the opposite order. Inspect the cache key and any shared memoisation inside the application. A correctly scoped database query can still be undermined by an incorrectly scoped cache that returns the previous caller's result.

For retrieval systems, test both the initial search and the later fetch of a cited document. Filtering search results does not secure a separate document-download endpoint. Use a reference that the caller could guess or obtain from an old log and verify that the fetch performs its own authorisation.

Follow asynchronous work after permissions change

Queue a synthetic action while tenant A's operator is authorised, then remove the relevant permission before the worker dispatches it. Define whether the action must stop, be re-approved or complete under a narrowly specified durable grant. Test the chosen behavior at execution time. Do not let a queue message become an indefinite copy of old authority.

Repeat with a retry after the operator has changed tenants. The retry must refer to the original tenant-bound operation and current rules. A fresh user session must not accidentally redirect the old job into the new tenant. Preserve the operation identity and reject conflicting context rather than guessing the intended destination.

Observe the receiver, not just the error message

A gateway can return an error after the protected system has already accepted an action. For each denial test, inspect the synthetic receiver or its transaction record to confirm that no forbidden action occurred. Record the gateway decision and receiving-system observation independently. If they disagree, treat the case as a failed control even if the user saw “access denied.”

Check logs and error responses for cross-tenant content too. An exception handler that prints an entire retrieved object can leak data through monitoring while the normal response remains clean. Use synthetic canary strings to search the relevant test logs and exports. Do not introduce real secrets or personal data just to make a leak detectable.

Recover from a failed isolation test

Stop the affected test path, preserve evidence and determine which boundary first lost the trusted context. Avoid a superficial fix that adds a filter only to the visible response. Repair the point of authority or storage selection, then rerun the paired cases through every affected path, including background work and exports.

If the finding may affect an existing deployment, follow the organisation's incident process to determine scope and notification responsibilities. This article does not determine legal duties. Keep the technical record precise: what was accessible, under which identity, for which period and with what observed consequences.

Define an acceptance record the team can repeat

Save fixture identifiers, candidate version, expected behavior and observed receiver state for each case. Include a positive control proving that legitimate access still works; a gateway that denies everything has not demonstrated a useful isolation implementation. Keep positive and negative results separate so availability improvements do not hide access regressions.

Run the matrix after changes to identity mapping, routing, credential selection, storage keys or queue execution. A completed test on one gateway version does not establish isolation for a later architecture. The useful outcome is a repeatable boundary test owned by the platform team, with a visible failure when another tenant's context is substituted.

Use the worksheet and related implementation guides

Use the parent guide for the wider architecture, then apply this article to one bounded implementation. The adjacent articles cover related decisions without replacing this worksheet.

Download the editable worksheet. Next step.

Engineering draft, 18 October 2026. Primary sources checked on this date; specialist review remains pending. The worksheets describe proposed tests, not measured customer results. OATI remains a developer preview. Local implementation evidence does not establish independent assurance, customer acceptance or production readiness for a particular deployment.