Sandboxing Code-Executing Agents: Container Isolation, Seccomp, and Egress Allowlists



Sandboxing Code-Executing Agents: Container Isolation, Seccomp, and Egress Allowlists

TL;DR: Code-executing agents turn model output into running processes, so the sandbox becomes part of your threat model. Combine three layers — locked-down containers, a restrictive seccomp profile, and an egress allowlist — with a policy decision point that sits before any provider or tool call. Add delegated identity, just-in-time credentials, approval checkpoints, fail-closed defaults, and an audit trail, and you have a practical ai agent security infrastructure baseline you can build and test incrementally.

AI agents that write and run code — a data-analysis agent executing Python, a DevOps agent running kubectl, an research agent invoking scripts — move risk from “bad output” to “bad execution.” The model’s generated code runs with real syscalls, real network access, and often real credentials. This tutorial walks you through a layered sandbox design: container isolation, seccomp filtering, and egress allowlists, then wraps them in the identity, policy, and audit controls that make the system operable in production.

What You Will Learn

Table of Contents

Map the Agent Attack Surface

Before writing configuration, enumerate what an attacker (or a hallucinating model) can reach. Treat each item as a control surface:

  1. Identity — Is the agent acting as itself, or as a shared service account that also runs your batch jobs?
  2. Prompts and memory — Injected instructions in retrieved documents or tool results can redirect execution.
  3. Tools and connectors — Every MCP server, browser tool, or database connector widens the callable surface.
  4. Credentials — Long-lived keys in environment variables are the most common failure.
  5. Data — Generated code can read files inside the sandbox, including anything mounted in.
  6. Network egress — Unrestricted outbound access enables data exfiltration and package-install supply-chain attacks.
  7. Multi-step execution — An agent that loops over steps can chain individually harmless actions into a harmful sequence.

The key insight: hardening only the container addresses items 5 and 6. Identity, credentials, and policy must be handled outside the runtime — which leads to the architecture.

Reference Architecture for AI Agent Security Infrastructure

The pattern that scales is a governed gateway — an authorization and policy boundary between the agent runtime and everything external.

[Human user]
    |
    v
[Agent runtime] --> [Policy gateway] --> [LLM provider]
   sandboxed          allow/deny/approve   [Tools / MCP / APIs]
   no long-lived      scoped grants        [Cloud (e.g. AWS)]
   credentials        evidence log         [Databases]

Rules of the road:

This is the same principle behind an ai agent security gateway: policy is evaluated before provider access, not after. Commercial offerings differ in features, so verify current capabilities against primary vendor documentation rather than assuming parity. With the boundary defined, we can harden what runs behind it.

Step 1: Container Isolation

Start by removing every privilege the agent does not need. A useful baseline for a code-executing agent:

# docker-compose.agent.yml
services:
  agent-sandbox:
    image: agent-runtime:1.4
    read_only: true
    user: "10001:10001"
    cap_drop:
      - ALL
    security_opt:
      - no-new-privileges:true
    tmpfs:
      - /tmp:size=64m,noexec,nosuid
    volumes:
      - ./workspace:/workspace:rw   # only the agent's own scratch dir
    pids_limit: 256
    mem_limit: 1g
    cpus: 1.0
    networks:
      - sandbox-net   # isolated network; egress filtered separately

Key decisions:

For stronger guarantees, run each session in a microVM (Firecracker, Cloud Hypervisor) or a gVisor/Kata runtime when the workload is untrusted enough to justify the overhead. Containers are a strong baseline, not a perfect boundary.

Step 2: Seccomp and Kernel Hardening

seccomp filters which syscalls a process may make. Docker and containerd ship a default profile; for agents, start from it and deny aggressively.

{
  "defaultAction": "SCMP_ACT_ERRNO",
  "architectures": ["SCMP_ARCH_X86_64"],
  "syscalls": [
    {
      "names": ["read", "write", "exit", "exit_group", "brk", "mmap",
                "futex", "clock_gettime", "openat", "stat", "fcntl"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

In practice you will iterate: run your agent’s test suite, log EPERM failures, and allow only what legitimate workloads require. Deny by default on these high-risk families:

Syscall family Why it is dangerous
mount, umount2, pivot_root Filesystem manipulation, escape attempts
ptrace, process_vm_readv Read other processes’ memory
keyctl, add_key Kernel keyring access
clone with unusual flags Namespace manipulation
bpf Load eBPF programs

Apply it and harden the kernel surface:

docker run --security-opt seccomp=agent-seccomp.json \
  --security-opt no-new-privileges=true \
  --cap-drop=ALL agent-runtime:1.4 python analyze.py

Also disable unused kernel features at the host level (unprivileged_userns_clone=0 where your distro allows it), keep the host patched, and separate agent hosts from CI and production workloads. Kernel hardening only helps if you patch — which is why monitoring comes later.

Step 3: Egress Allowlists

Unfiltered outbound network access negates most of the work above: generated code can exfiltrate data, pip install from a typosquatted package, or reach metadata endpoints.

Deny by default, then allow only what the task requires:

# Example egress policy (expressed as policy, implement with
# gateway, proxy, iptables/ebpf, or a service mesh)
egress:
  default: deny
  allow:
    - host: api.openai.com
      port: 443
      purpose: LLM provider via gateway
    - host: pypi.org
      port: 443
      purpose: approved package mirror
    - host: internal-artifact.corp.example
      port: 443
      purpose: internal libraries
  deny_explicit:
    - 169.254.169.254    # cloud metadata service
    - "*.duckdns.org"     # common exfil channels

Practical notes:

With isolation, syscalls, and network locked down, the remaining gap is who the agent is allowed to act as.

Step 4: Identity, JIT Credentials, and Approvals

Sandboxing constrains what code can do; identity constrains what the agent is allowed to do. Combine them:

# Pseudocode: policy decision before any tool or provider call
def handle_tool_call(agent, request, human_principal):
    identity = bind_identity(agent.id, human_principal)   # agent != shared svc acct

    grant = issue_jit_credential(                         # seconds-to-minutes TTL
        identity=identity,
        scope=request.required_scope,                     # exact resources
        resource=request.target,                          # resource-bound
    )

    decision = policy.evaluate(identity, request)

    if decision.action == "deny":
        audit.log(identity, request, "denied", decision.reason)
        return Denied(decision.reason)
    if decision.action == "require_approval":
        audit.log(identity, request, "pending")
        if not wait_for_human_approval(request, timeout="10m"):
            return Denied("approval timeout")             # fail closed
    return execute_with(grant, request)

Non-negotiable behaviors:

This separation also means rotating or revoking authority does not require rebuilding the agent image — a common failure in credential-in-image setups.

Testing and Monitoring the Sandbox

A control you have not tested is an assumption. Build a small adversarial suite:

# 1. Verify the seccomp profile actually blocks high-risk syscalls
docker run --security-opt seccomp=agent-seccomp.json agent-runtime:1.4 \
  python -c "import ctypes; ctypes.CDLL(None).prctl(22, 0)"   # expect EPERM

# 2. Verify egress default-deny
docker exec sandbox curl -s --max-time 5 https://example.com && echo "FAIL: open egress"

# 3. Verify no metadata access (run inside an AWS workload)
docker exec sandbox curl -s --max-time 3 http://169.254.169.254/ && echo "FAIL: IMDS reachable"

# 4. Verify fail-closed: stop the policy gateway, re-run a tool call
#    Expected result: Denied, not silently executed

Monitor continuously:

Ship these as CI checks so a misconfiguration (a dropped cap_drop, an accidentally allow-all egress rule) fails the build instead of reaching production.

Governance, Audit Evidence, and Incident Response

Technical controls need operational scaffolding:

With controls, tests, and evidence in place, you have a defensible baseline — and a clear backlog of the next risks to reduce.

Conclusion

Sandboxing a code-executing agent is not one setting but a stack: container isolation limits what the process can touch, seccomp limits which syscalls it can make, and egress allowlists limit where it can send data. Wrapped around that runtime, ai agent security infrastructure adds the pieces a sandbox alone cannot provide — distinct identity bound to a human, delegated and resource-bound grants, just-in-time credentials, approval checkpoints, fail-closed defaults, and a linked evidence trail. Build it in that order: isolate, filter, constrain the network, then govern identity and prove it with tests. Each layer reduces a different failure mode, and together they turn an agent that can execute code into one you can safely let execute code.

FAQ

1. Why isn’t a Docker container enough to secure a code-executing AI agent? Containers share the host kernel and often run with permissive defaults. Without seccomp, dropped capabilities, resource limits, and network restrictions, generated code can probe the host, exhaust resources, or exfiltrate data. The container is one layer, not the boundary.

2. What is an ai agent security gateway and where does it sit? It is an authorization and policy layer between the agent runtime and LLM providers, tools, and APIs. Every call is evaluated for allow, deny, or human approval before it leaves the agent, and credentials are issued just-in-time rather than stored in the runtime.

3. How do I stop an agent from exfiltrating data over the network? Default-deny egress with an explicit allowlist of required hosts, enforced by a logging proxy or network policy. Block cloud metadata endpoints, pin packages to an internal mirror, and log every destination for review.

4. What does least privilege mean for agent credentials? Issue short-lived credentials scoped to the exact resources a single step requires — for example, read access to one bucket prefix for 15 minutes — instead of a standing role. Revoke the grant without redeploying the agent when the task ends.

5. How does aws ai agent security differ from sandbox hardening? Sandbox hardening governs what code can do at runtime. AWS-side controls govern where it runs and what it can reach: IAM conditions, IMDSv2, VPC and egress controls, and centralized logging. You need both; neither substitutes for the other.

Further Reading

  1. NIST SP 800-190 — Application Container Security Guide — the foundational reference for container threat modeling, image security, and runtime hardening.
  2. Docker Security — Seccomp in Docker — official documentation on writing and applying custom seccomp profiles.
  3. OWASP AI Security and Privacy Guide — broader guidance on securing AI systems, including agent-specific risks and governance practices.

Want a second set of eyes on your architecture? If you are designing sandboxing, identity, or policy controls for your agents, we are happy to walk through your ai agent security infrastructure with you — no pitch required. Book a 30-minute conversation: https://cal.id/axec/demo?duration=30

Start where you are

Have a workflow
worth rethinking?

Bring us the problem, not a predetermined solution. We will help you identify the opportunity, map the path to production and define what success looks like.

Start an AI discovery session AI opportunity workshop / proof of value / engineering pod / enterprise transformation