When Anthropic published their containment architecture for Claude-based agents, something clicked for me that fifteen years of security engineering had been building toward: AI agents need the same security model we already apply to untrusted user code.
Not a softer version. Not “trust but verify.” The exact same model — isolation first, capability grant second, audit everything.
The problem is that most teams deploy agents the opposite way. They give the agent broad access because it’s “their” system, then try to constrain it after incidents occur. This is how you get agents that accidentally delete production data, exfiltrate secrets into LLM context windows, or get manipulated into misusing their own legitimate permissions.
The Core Insight: Agents Are Untrusted Code
Here’s the mental model shift: an AI agent is not your colleague. It is a process that executes arbitrary instructions derived from language models, user inputs, and tool outputs — any of which can be adversarially crafted.
The moment you accept this, the security architecture becomes obvious. You already know how to sandbox untrusted code. You do it for browser JavaScript, for containerized microservices, for payment processing sandboxes. The techniques transfer directly.
Anthropic’s containment framework organizes this into four layers, each addressing a different attack surface.
Layer 1: Process Isolation
The first boundary is computational. An agent’s execution environment should have no access to host-level resources beyond what is explicitly granted.
In practice, this means containers — but not just Docker with default settings. You need:
- Read-only root filesystem — the agent cannot modify its own runtime
- Dropped Linux capabilities — no
CAP_NET_ADMIN, noCAP_SYS_ADMIN, no privilege escalation paths - Resource quotas — CPU, memory, and I/O limits prevent runaway inference loops from taking down adjacent services
- No shared kernel namespaces — each agent instance runs in its own PID, network, and mount namespace
In .NET, this maps cleanly to running your agent worker in a container with --cap-drop ALL --cap-add NET_BIND_SERVICE --read-only --tmpfs /tmp. The application itself runs as a non-root user with no write access outside designated scratch paths.
For teams not yet on containers, .NET’s AppDomain historically provided isolation boundaries, but in .NET 5+ the recommendation is container-level isolation. AppDomain isolation is gone — embrace the container model.
Layer 2: Filesystem Sandboxing
Process isolation handles the compute boundary. Filesystem sandboxing handles the data boundary.
An agent should operate within a scoped working directory with no access to host paths, other agents’ workspaces, or secret stores. The principle is simple: if the agent doesn’t need it to complete the task, it cannot see it.
Anthropic’s model adds a useful refinement: ephemeral workspaces by default. The agent’s working directory is created fresh per task and destroyed on completion. Anything that needs to persist must be explicitly written to a durable store through a controlled interface — not via direct filesystem access.
In .NET, implement this with a workspace factory:
public async Task<AgentWorkspace> CreateEphemeralWorkspace(string taskId)
{
var path = Path.Combine(_baseDir, "agent-workspaces", taskId);
Directory.CreateDirectory(path);
// Chroot equivalent: all agent file ops go through this abstraction
return new AgentWorkspace(path, maxSizeBytes: 100 * 1024 * 1024);
}
The AgentWorkspace class validates every path operation against the root — no ../ escapes, no symlink traversal, no absolute paths outside the sandbox. This is exactly how you’d build a secure file upload handler, applied to agent execution.
Layer 3: Network Egress Control
This is the layer most teams skip, and it’s where the most damaging breaches occur.
An agent with unrestricted network access can: exfiltrate data to attacker-controlled endpoints, call external APIs without authorization, make requests that bypass your rate limiting and audit logging, and become a vector for supply-chain attacks if its tool implementations fetch remote content.
Anthropic’s approach is an egress allowlist: the agent can only reach pre-approved endpoints, and every outbound connection is logged with the agent’s identity, the target, and the tool that initiated it.
In Kubernetes, this is a NetworkPolicy. In Docker Compose, you add an egress proxy (Squid or Envoy work well). In AWS, it’s a VPC with egress through an inspecting NAT Gateway and Security Groups that whitelist only necessary destinations.
For .NET HttpClient, enforce this at the HttpMessageHandler level so it cannot be bypassed:
public class EgressGuardHandler : DelegatingHandler
{
private readonly HashSet<string> _allowedHosts;
protected override async Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken ct)
{
var host = request.RequestUri?.Host;
if (host == null || !_allowedHosts.Contains(host))
throw new SecurityException($"Egress blocked: {host}");
_logger.LogInformation("Agent egress: {Host} via {Tool}", host, _currentTool);
return await base.SendAsync(request, ct);
}
}
Register this as the innermost handler in your HttpClient factory. The agent’s LLM calls, tool implementations, and any HTTP operations all flow through it.
Layer 4: Tool Permission Scoping
The fourth layer is the most semantically rich: controlling what the agent can do, not just where it can go.
Anthropic’s tool permission model works like OAuth scopes. Each tool is declared with the minimum capability set it requires. The agent is granted a subset of available tools per task, based on what that task legitimately needs. Tools themselves are restricted to specific resource scopes — a file-reading tool can only read files in the current workspace, not arbitrary paths.
The “confused deputy” problem is critical here. A confused deputy attack works like this: a malicious input convinces your agent to use a legitimate, high-privilege tool in a way the system designer didn’t intend. The agent isn’t compromised — it’s doing exactly what it’s authorized to do, just in a context an attacker constructed.
The defense is intent binding: tools should validate not just that the agent can perform an operation, but that the operation matches the declared intent of the current task. A customer support agent shouldn’t be able to invoke database write tools regardless of what a user message says, because database writes are outside the declared scope of customer support tasks.
In .NET, model this as a capability token granted at task creation:
public record AgentCapabilities(
IReadOnlySet<ToolName> AllowedTools,
IReadOnlySet<string> AllowedResourcePrefixes,
bool CanWriteExternalSystems,
TimeSpan MaxExecutionTime
);
Every tool invocation validates the capability token before executing. The token is non-mutable once issued. Even if the agent’s LLM generates a tool call outside its granted scope, the runtime rejects it before execution.
Production Containment Checklist
Before deploying any agent to production, verify these ten controls:
- Container runs as non-root with read-only root filesystem
- All Linux capabilities dropped except those explicitly needed
- Ephemeral workspace created per task, destroyed on completion
- Egress allowlist enforced at network layer, not application layer
- Every outbound connection logged with agent identity and initiating tool
- Tool allowlist per task type — no single agent role has access to all tools
- Resource scope validation in every tool — paths, resource IDs, account scopes all checked
- Maximum execution time enforced with hard timeout, not just soft cancellation
- Audit log for every tool invocation including inputs, outputs, and duration
- Incident response playbook that can revoke agent credentials and terminate sessions within 60 seconds
The last one is underrated. Containment eventually fails — the question is how fast you can respond when it does.
Why This Matters More Than Ever
As agents move from demos to production systems that touch real data and real money, the security surface area grows proportionally. The teams that will ship safely at scale are the ones that treat agent containment as a first-class engineering concern — not a compliance checkbox applied after launch.
Anthropic’s framework isn’t exotic. It’s disciplined application of security principles we’ve held for decades, adapted to a new execution environment. If you’ve built secure microservices, you already have most of the mental model. The translation to agents is the work.
Start with Layer 1. Containerize with minimal privileges. Everything else builds from there.