The Model Context Protocol (MCP) promised to solve a real problem: giving LLMs safe, structured access to external systems. It’s a clean abstraction — servers that expose tools, clients that consume them, and a protocol that keeps everything organized.
But clean abstractions don’t automatically mean secure systems.
We’ve spent the last year building data infrastructure for AI agents, and one thing has become clear: MCP solves the interface problem, not the security problem. It’s a framework for connecting things, but it doesn’t address the fundamental risks that come with those connections.
The Real Problem with MCP
MCP servers are essentially privileged deputies. They hold credentials, they execute commands, and they operate with broad permissions. Once compromised, they become perfect vehicles for lateral movement and data exfiltration.
The attack surface is familiar:
- Supply chain vulnerabilities — third-party MCP servers with undisclosed access patterns
- Prompt injection — malicious inputs that trick the LLM into misusing its tools
- Credential reuse — stolen tokens that grant standing access to sensitive systems
- Tool chaining — cascading permissions across multiple MCP servers
The Cloud Security Alliance recently published a paper on MCP threats and secure enterprise adoption. It’s worth reading — not because MCP is uniquely dangerous, but because it inherits every authentication and authorization risk we’ve been fighting for years.
The Confused Deputy Problem
At its core, this is a confused deputy attack. A program with elevated privileges is tricked into misusing its authority by another program with fewer rights.
We’ve seen this pattern play out in SQL injection, cross-site scripting, and now in LLM tool use. The mechanics change, but the fundamental vulnerability remains: standing permissions are too broad, too long-lived, and too easy to abuse.
Consider a simple SQL injection scenario:
function getUserProfile(userID) {
const query = `SELECT name, email FROM users WHERE id='${userID}'`;
return db.execute(query);
}
const maliciousInput = "123' UNION SELECT username, password FROM admin_users WHERE 1=1--";
getUserProfile(maliciousInput);
The function has legitimate access to the database. It’s doing its job. But it’s been tricked into doing more than intended.
MCP servers face the same challenge. They’re designed to execute tasks on behalf of an LLM, but without fine-grained controls, they can be manipulated into doing far more.
The Pattern We Keep Seeing
Look at the major breaches from the last two years:
- Snowflake (2024): Credential reuse and missing MFA led to data exfiltration
- Football Australia (2024): Developer accidentally committed plaintext IAM credentials
- Toyota (2023): Developer tool logged cloud credentials to a local file
- Microsoft (2024): Legacy test account compromised via password spraying
- Retool/Fortress (2023): Phished credentials and OTP led to $15M crypto theft
- FTX (2022): SIM swap attack bypassed OTP protections, resulting in $400M+ loss
Seven out of eight of these incidents involved credentials and standing permissions. The only exception was CrowdStrike’s registry write issue — a software bug, not an access problem.
The common thread isn’t weak passwords or bad actors. It’s that once credentials are compromised, the blast radius is massive. Standing permissions grant broad, persistent access that can be exploited long after the initial breach.
Proxies Aren’t the Answer
The instinct is to add a proxy layer — something that sits between the application and the data, enforcing access controls.
We’ve tried this. It doesn’t work.
Here’s why:
Static, Broad Permissions
Proxies rely on role-based access control (RBAC). Roles are static. They’re assigned once and remain in place until manually revoked. This violates the core principle of Zero Standing Privilege (ZSP).
No Just-in-Time Granularity
Proxies manage connections, not data. They can block access to a database, but they can’t dynamically control access to specific rows or columns based on context. A compromised credential can still execute SELECT * and exfiltrate everything.
Large Blast Radius
Because permissions are broad, a single compromised credential enables lateral movement across the entire database. There’s no containment, no isolation.
No Isolation
Proxies don’t create temporary, isolated environments. They’re pass-through mechanisms. If an attacker gets in, they’re in.
Enter the Data Enclave
A data enclave is a fundamentally different approach. Instead of granting broad access and hoping for the best, it provisions a secure, isolated environment for each access request.
Think of it as a man trap — a transitional space with controlled entry and exit.
How It Works
- Request: A user or agent requests access to specific data with a defined purpose and time limit.
- Provision: The enclave is created, containing only the requested subset of data.
- Access: The user or agent interacts with the data inside the enclave.
- Teardown: Once the time limit expires, the enclave is destroyed.
Access is brokered, not granted. Permissions are ephemeral, not standing.
Data Contracts Replace Connection Strings
Instead of handing out database credentials, you define a data contract:
{
"contract_id": "CT-2025-010",
"name": "Financial data access",
"requester": "Nico Bistolfi",
"duration": "24h",
"justification": "There's a bug in the dashboard",
"dataAccess": [
{
"source": "financial_db",
"table": "account_data",
"columns": ["account_type", "account_status"],
"filter": "customer_id = 20"
},
{
"source": "snowflake_prod",
"table": "customer_data",
"columns": ["first_name", "email"],
"filter": "email LIKE '%@company29.com'"
}
]
}
This contract specifies:
- Who can access the data
- What data can be accessed (specific tables, columns, and rows)
- How long access is granted
- Why access is needed
If the request is approved, an enclave is provisioned with only the specified data. Once the 24 hours expire, the enclave is torn down.
The Architecture
Here’s what it looks like in practice:
The gateway validates the request, provisions the enclave, and fetches only the necessary data. The authenticated device never touches the underlying resources directly.
If the enclave is compromised, the blast radius is limited to the data subset it contains. There’s no lateral movement, no standing permissions, no broad access.
Why This Matters for AI
AI agents operate with a different risk profile than traditional applications. They’re non-deterministic. They interpret inputs, generate commands, and execute actions based on probabilistic reasoning.
That makes them inherently vulnerable to manipulation. Prompt injection isn’t a theoretical risk — it’s a daily reality.
Data enclaves provide containment. Even if an agent is tricked into requesting more data than it should, the enclave limits what’s available. Even if credentials are stolen, they’re ephemeral and scoped to a specific task.
This isn’t about making AI safe. It’s about making AI failures less catastrophic.
What We’ve Learned
We’ve built systems that provision data enclaves for AI agents at scale. Here’s what works:
1. Ephemeral credentials are non-negotiable
Every enclave gets unique, short-lived credentials. No credential reuse, no rotation headaches. When the enclave terminates, the credentials die with it.
2. Approval workflows must be async
Not every request can be auto-approved. Build for human-in-the-loop from day one. Your compliance team will thank you.
3. Audit everything
Log every request, every approval, every query executed inside the enclave. When (not if) something goes wrong, you need a complete paper trail.
4. Start with read-only
Write access multiplies your risk surface. Get read-only enclaves right first, then carefully expand to write operations with additional controls.
5. Make teardown automatic
Manual cleanup fails. Use TTLs at every layer: credentials, network policies, the enclave itself. Nothing should require intervention to shut down.
The Path Forward
MCP isn’t going away. It’s a useful protocol for structuring LLM integrations. But it’s not a security model.
The industry will follow one of two paths:
Path A: Bolt security onto MCP through layers of proxies, policy engines, and monitoring tools. This is where we’ve been for the last decade with APIs and microservices. It’s complex, brittle, and still vulnerable to credential compromise.
Path B: Embrace brokered access and ephemeral environments. Treat every data request as untrusted until proven otherwise. Provision the minimum necessary access, revoke it automatically, and contain the blast radius from the start.
We’re betting on Path B.
Getting Started
If you’re building AI agents with access to production data, start here:
-
Inventory your standing permissions — what credentials are floating around? How long do they live? What can they access?
-
Define your data contracts — for each integration, specify exactly what data is needed, who needs it, and for how long.
-
Build approval workflows — auto-approve the safe stuff, flag the rest for human review.
-
Implement automatic teardown — set hard TTLs on everything. No exceptions.
-
Audit relentlessly — log every access request and every query. Make it searchable.
The goal isn’t perfect security. It’s containment. When something goes wrong — and it will — you want the damage limited to one enclave, not your entire data estate.