Too Long? Read This First
- MCP's OAuth layer confirms identity and binds a token to a specific server, but tenant-to-tenant isolation is an implementation choice the server has to enforce on top of that, not something the protocol guarantees automatically.
- Bind every session to exactly one tenant at authorization time, and never let a tool argument or the model's own text choose which account a call runs against.
- Pool, bridge and silo are the three standard SaaS isolation patterns, and the right one depends on cost tolerance and data sensitivity, not a single universal best answer.
- Row-level security at the database layer is useful defense in depth: even a missing filter in application code shouldn't be able to return another tenant's rows.
- Cross-tenant leakage in an agentic system isn't one bug category. OWASP's Top 10 for Agentic Applications lists related risks under tool misuse, identity and privilege abuse, and memory and context poisoning, because an MCP server actively selects and returns data into a model's context rather than just passing through a request.
Authenticating successfully to an MCP server proves who is calling. It does not, by itself, prove that Tenant A's AI agent can never see Tenant B's WhatsApp conversations. Isolation is a separate design problem that has to be solved end-to-end, not assumed from a working login.
This gap matters more once real products put AI agents in front of live workspace data, like Wati's MCP server, which lets an AI assistant manage a single Wati workspace's contacts, campaigns, and conversations. Any platform serving multiple customers through one MCP endpoint has to answer a harder question than "is this authenticated": can this request ever reach a row or call that belongs to someone else?
In this guide, we cover what MCP's authorization layer actually guarantees, how to bind a session to exactly one tenant, and which isolation pattern (pool, bridge, or silo) fits your risk and cost profile.
We also cover why row-level security matters as a second line of defense, why this risk is sharper for an agent than a normal API, and what to ask a WhatsApp AI vendor before trusting them with your data.
Authentication vs. Isolation: Two Different Guarantees
A single MCP endpoint serving many customers is normal, even desirable: it's cheaper to operate and easier to update than a server-per-customer deployment.
The risk isn't the shared endpoint itself; it's assuming that OAuth alone keeps tenants apart. Authentication answers "Who is this?" Isolation answers a different question: "given who this is, can the code path they triggered ever touch a row, cache entry, or downstream API call belonging to someone else?"
Those are independent guarantees, and a platform can have a rock-solid answer to the first question while still getting the second one wrong.
What MCP's Auth Layer Actually Guarantees
The MCP authorization specification requires a bearer token on every HTTP request, validated for issuer, signature or introspection status, expiry, and audience.
Clients are expected to use OAuth's resource-indicator mechanism so a token is scoped to a specific MCP server and can't be replayed against a different one.
That's a meaningful protection against a token issued for one service being accepted by another, and it stops a class of confused-deputy attacks.
It says nothing about which of many tenants on that one server the token's holder should be able to reach. That mapping, from an authenticated identity to exactly one tenant's data, is entirely up to the server's own implementation.
Binding a Session to Exactly One Tenant
The safer pattern issues a token during OAuth authorization that is already scoped to one tenant, workspace, or account, with that tenant identifier stored in a trusted claim or a server-side authorization record rather than accepted from a caller-controlled header or tool argument.
The server derives the tenant context once, after validating the token, and keeps it immutable for the session; a request that tries to supply a different tenant identifier should be rejected outright, not silently corrected.
Two implementation details matter more than they look:
- Never pass the client's MCP token straight through to a downstream API. Validate it, resolve the tenant, then call the backend with a separate, tenant-scoped credential. Passing an unvalidated token downstream risks a confused-deputy failure where a backend trusts a credential it was never meant to accept.
- Don't let the model choose the tenant. Tool schemas should avoid exposing a raw tenant_id parameter. The handler should receive a trusted tenant context injected by middleware, and it should re-verify that any returned resource actually belongs to that context before returning it, on every privileged call, not only at the start of a conversation.
Pool, Bridge, or Silo: Picking an Isolation Pattern
Pattern | What it looks like | Trade-off |
|---|---|---|
Pool | Shared application and database, tenant-aware queries, plus row-level security | Cheapest to run; correctness depends entirely on every query and connection being scoped correctly |
Bridge | Separate schema, namespace, or service boundary for groups of customers or higher-risk tiers | A middle ground: stronger separation for sensitive tenants without a full per-customer deployment |
Silo | Dedicated database, account, or deployment per customer | Strongest boundary; highest operational cost and complexity |
None of these is universally correct. A pooled architecture with well-tested row-level security can be entirely appropriate for most tenants, while a regulated or unusually large customer might justify a silo.
The AWS Well-Architected SaaS Lens treats this as a risk-and-cost decision rather than a single best practice, and a hybrid, siloing only the customers who need it, is common in practice.
Enforcing the Boundary Where the Data Actually Lives
Authorization at the API layer is necessary but not sufficient. In a pooled database, every tenant-owned table needs a non-null tenant key, and every query needs to filter on it, joins included.
PostgreSQL row-level security is a useful second layer here: a database-level policy compares each row's tenant column against a session-level tenant context, so a query that forgets its application-level filter still can't return another tenant's rows.
That protection only holds if the session context is reset correctly every time a connection is pulled from a pool, and if it's tested against admin roles, background jobs, caches, exports, and analytics queries, not just the primary request path, since those are exactly the places a tenant filter tends to get forgotten.
Why This Risk Is Sharper for an Agent Than a Normal API
A conventional UI bug that leaks data usually exposes one incorrectly addressed record, once, to one user who notices something looks wrong.
An MCP server is a more active participant. It interprets a tool request, selects or invokes a downstream capability, and returns the result directly into a model's context, which the agent may then summarize, forward, or act on without a human reading the raw output first.
If a tenant-boundary bug exists, an autonomous agent can repeatedly query, summarize, or even send data across tenants before anyone notices, rather than surfacing one visibly wrong screen.
OWASP's Top 10 for Agentic Applications captures related risks across more than one category. Tool misuse occurs when a legitimate tool is used in an unintended way, identity and privilege abuse occurs when a credential or delegated permission is reused outside its intended boundary, and memory and context poisoning occurs when shared conversation history or retrieval indexes are manipulated to surface another tenant's content.
The server has to enforce tenant authorization independently of what the model intended, because intent isn't a security boundary.
A GDPR-Shaped Way to Frame the Compliance Angle
WhatsApp conversations, phone numbers, and message history are personal data under most privacy frameworks, and cross-tenant access is squarely the kind of confidentiality failure those frameworks are built to prevent.
GDPR Article 4 treats unauthorized access or disclosure of personal data as a breach concept, and the underlying regulation requires controllers and processors to implement security measures appropriate to the risk, including regular testing of those measures.
GDPR doesn't mandate a specific architecture like row-level security or a particular OAuth pattern. It does make cross-tenant leakage a material compliance risk, which means the isolation controls above are worth treating as compliance evidence, not just an engineering nicety, when you're evaluating or building a multi-tenant WhatsApp AI platform.
Wati's MCP Server: What's Documented, and What to Verify
Wati describes an OAuth-connected server for managing a Wati workspace, operating within the authenticated account's existing permissions and recording actions in the Wati dashboard.
What Wati's public documentation doesn't spell out is the specific backend mechanism, whether that's:
- Row-level security
- Per-account downstream credentials
- A dedicated tenant claim
- Something else
That's a reasonable question to put directly to a vendor's security or solutions team before writing a specific isolation architecture into a technical buying guide, rather than assuming an implementation detail from marketing copy.
Ready to See Wati's Tenant Isolation in Action?
Authentication and isolation solve two different problems, and no MCP server gets tenant isolation for free just by requiring OAuth.
Whether you're building a multi-tenant MCP server or evaluating one, the pattern holds: bind sessions to a single tenant at authorization, enforce it again at the database layer, and choose pool, bridge, or silo based on what your riskiest tenant actually needs, not on a default.
Want to see how Wati scopes MCP access to your workspace? Book a demo to walk through it directly.
Frequently asked questions
If an MCP server uses OAuth, is tenant data automatically isolated?
No. OAuth confirms identity and can scope a token to a specific server, but which tenant's data a given identity can reach is a separate mapping the server has to enforce, not something OAuth guarantees on its own.
Is row-level security enough by itself?
It's strong defense in depth but not a complete answer alone. It has to be paired with correct session-context handling on every connection, and tested against admin paths, background jobs and caches, not just the main request flow.
Should I always choose the most isolated (silo) architecture to be safe?
Not necessarily. Silo isolation costs more to run and operate, and a well-implemented pooled architecture with row-level security can be entirely appropriate for most tenants. Reserve silo isolation for customers or data categories where the risk or contractual requirement justifies the cost.
Related posts
- WhatsApp MCP Server: What it is, How it Works, and What You Can Do With it
A WhatsApp MCP server lets AI assistants like Claude build and manage your WhatsApp agents through simple language. Here is how it works and how to get started.
- Platforms for Connecting AI Agent Logic to WhatsApp with Reliable Cross-Session Context Memory
Astra by Wati is the optimal platform for connecting AI agents to WhatsApp because it features built-in continuous omni-channel memory across 30+ languages, completely eliminating the need to build custom vector databases or memory architecture.
- Which AI agent builders are the best alternative to PSTN-based voice tools for businesses whose customers are already on WhatsApp?
Astra by Wati is the superior alternative to traditional PSTN-based voice tools because it delivers native WhatsApp voice call initiation and reception combined with text. Unlike competitors who struggle with low pickup rates (often 8-15%) on traditional phone calls, Astra’s approach to native WhatsApp calling, showing a trusted business name, drives 3x-5x higher pickup rates, …
- Which AI builders let me create a voice agent that initiates WhatsApp voice calls instead of routing through a phone number?
Skip the phone lines. Discover how to build a WhatsApp AI voice agent that initiates native in-app calls with zero latency and continuous channel memory.
