12 min read
Dillon Browne

Secure AI Coding Agents with Containers

Master container isolation for AI coding agents. Transform security risks into production-ready DevOps tools with Docker, Kubernetes, and proven patterns.

ai devops docker kubernetes security
Secure AI Coding Agents with Containers

AI coding agents have created a fascinating security paradox: tools that automate development work but demand near-unlimited system access. In my years architecting cloud infrastructure and DevOps pipelines, I’ve learned that unrestricted access is a recipe for disaster—whether it’s a developer, a service account, or an AI coding agent running in production.

The recent trend toward AI coding assistants running with full filesystem access and arbitrary command execution scares me. Not because the technology isn’t impressive, but because we’re repeating the same security mistakes we spent decades fixing in traditional infrastructure.

Let me share what I’ve learned about making AI agents safe without neutering their usefulness.

The Security Risk: AI Agents with Unlimited Access

Most AI coding agents today run in a single process with permissions equivalent to the user who launched them. This means:

  • Full read/write access to your entire filesystem
  • Ability to execute any command
  • Access to environment variables and secrets
  • Network access to internal and external services
  • No audit trail of what files were actually modified

I’ve seen production incidents caused by far less. Giving an AI agent these permissions is like handing root access to an intern—well-intentioned, but fundamentally unsafe.

The risk isn’t just theoretical. AI agents can:

  • Accidentally delete critical files during code refactoring
  • Expose secrets by logging them or including them in commits
  • Make network requests to malicious endpoints if prompted cleverly
  • Modify system configurations when attempting to “fix” dependency issues

Deploy Container Isolation for AI Agent Security

The solution I’ve implemented across multiple organizations starts with containerization. Not Docker containers for deployment—though that’s part of it—but ephemeral, purpose-built containers for each AI agent session.

Here’s the basic architecture I use:

#!/bin/bash
# Launch AI agent in isolated container

# Create ephemeral container with limited capabilities
docker run --rm \
  --name "ai-agent-$(uuidgen)" \
  --network none \
  --read-only \
  --tmpfs /tmp:rw,noexec,nosuid,size=100m \
  --cpus=2 \
  --memory=4g \
  --cap-drop ALL \
  --cap-add CHOWN,SETUID,SETGID \
  --security-opt no-new-privileges \
  -v "$(pwd)/workspace:/workspace:rw" \
  -v "$(pwd)/allowed-tools:/tools:ro" \
  ai-agent:latest \
  /tools/agent-runner

This gives us:

  1. Filesystem isolation: The agent can only access the mounted workspace directory
  2. No network access: --network none prevents any external communication
  3. Resource limits: CPU and memory constraints prevent resource exhaustion
  4. Minimal capabilities: Dropped all Linux capabilities except those strictly needed
  5. Read-only root: The container’s root filesystem is immutable

In my production deployments, I’ve extended this with overlay filesystems that let agents “think” they’re modifying system files while actually writing to a temporary layer that gets discarded.

Configure Kubernetes Sandboxing for AI Coding Agents

For organizations already running Kubernetes, the orchestration layer provides even better isolation through Pod Security Standards and RuntimeClass configurations.

Here’s a production-grade pod spec I use:

apiVersion: v1
kind: Pod
metadata:
  name: ai-coding-agent
  labels:
    app: ai-agent
    security.level: isolated
spec:
  runtimeClassName: gvisor  # Use gVisor for enhanced isolation
  securityContext:
    runAsNonRoot: true
    runAsUser: 65534
    fsGroup: 65534
    seccompProfile:
      type: RuntimeDefault
  
  containers:
  - name: agent
    image: ai-agent:v1.2.3
    
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
    
    resources:
      requests:
        memory: "2Gi"
        cpu: "1000m"
      limits:
        memory: "4Gi"
        cpu: "2000m"
    
    volumeMounts:
    - name: workspace
      mountPath: /workspace
      readOnly: false
    - name: tmp
      mountPath: /tmp
      
  volumes:
  - name: workspace
    persistentVolumeClaim:
      claimName: agent-workspace-pvc
  - name: tmp
    emptyDir:
      sizeLimit: 100Mi

The key additions here:

  • gVisor runtime: Provides an additional syscall filtering layer
  • PodSecurityPolicy enforcement: Prevents privilege escalation
  • Seccomp profiles: Restricts which system calls the container can make
  • Ephemeral storage: Temporary files automatically cleaned up

I’ve run thousands of AI agent sessions this way without a single security incident.

Implement Tool Allowlisting for AI Agent Security

Container isolation solves the “blast radius” problem, but we also need to control what the agent can execute. In my implementations, I use a tool allowlist approach:

# Tool proxy that validates and sandboxes agent commands

import subprocess
import shlex
from typing import List, Dict

ALLOWED_TOOLS = {
    "git": {
        "allowed_commands": ["status", "diff", "log", "add", "commit"],
        "forbidden_flags": ["--force", "-f"],
        "max_args": 10
    },
    "npm": {
        "allowed_commands": ["install", "test", "run", "audit"],
        "forbidden_flags": ["--unsafe-perm"],
        "max_args": 5
    },
    "python": {
        "allowed_commands": ["-m", "-c"],
        "forbidden_flags": [],
        "max_args": 20,
        "environment": {"PYTHONPATH": "/workspace/src"}
    }
}

def validate_command(tool: str, args: List[str]) -> bool:
    """Validate that command is allowed by policy"""
    if tool not in ALLOWED_TOOLS:
        return False
    
    config = ALLOWED_TOOLS[tool]
    
    # Check command allowlist
    if args and args[0] not in config["allowed_commands"]:
        return False
    
    # Check for forbidden flags
    for arg in args:
        if arg in config["forbidden_flags"]:
            return False
    
    # Check argument count
    if len(args) > config["max_args"]:
        return False
    
    return True

def execute_sandboxed(tool: str, args: List[str]) -> subprocess.CompletedProcess:
    """Execute command with sandboxing"""
    if not validate_command(tool, args):
        raise PermissionError(f"Command not allowed: {tool} {' '.join(args)}")
    
    env = ALLOWED_TOOLS[tool].get("environment", {})
    
    # Execute with timeout and resource limits
    return subprocess.run(
        [tool] + args,
        capture_output=True,
        timeout=30,
        env=env,
        cwd="/workspace"
    )

This proxy layer sits between the AI agent and the underlying system, enforcing policies even if the container is somehow compromised.

Configure Network Segmentation for AI Agent LLM APIs

AI agents need to call LLM APIs, but we don’t want them accessing arbitrary network endpoints. I solve this with a sidecar proxy pattern:

// LLM API proxy sidecar

import express from 'express';
import fetch from 'node-fetch';

const app = express();
const ALLOWED_ENDPOINTS = [
  'https://api.openai.com/v1/chat/completions',
  'https://api.anthropic.com/v1/messages'
];

app.post('/api/llm', async (req, res) => {
  const { endpoint, ...payload } = req.body;
  
  // Validate endpoint
  if (!ALLOWED_ENDPOINTS.includes(endpoint)) {
    return res.status(403).json({ error: 'Endpoint not allowed' });
  }
  
  // Strip sensitive headers
  const safeHeaders = {
    'Content-Type': 'application/json',
    'Authorization': `Bearer ${process.env.LLM_API_KEY}` // Injected by sidecar
  };
  
  try {
    const response = await fetch(endpoint, {
      method: 'POST',
      headers: safeHeaders,
      body: JSON.stringify(payload),
      timeout: 60000
    });
    
    const data = await response.json();
    res.json(data);
  } catch (error) {
    res.status(500).json({ error: 'LLM API call failed' });
  }
});

app.listen(8080, '127.0.0.1');

The agent container runs with --network none, then connects to this sidecar via a Unix socket. The sidecar handles all network communication with strict endpoint validation.

Production Lessons: Running Sandboxed AI Coding Agents

After running sandboxed AI agents in production for several months, here’s what I’ve learned:

Performance is acceptable: The overhead of container creation (100-200ms) is negligible compared to LLM API latency (2-10 seconds). Users don’t notice.

Debugging is harder: Sandboxing makes it more difficult to troubleshoot agent failures. I’ve added comprehensive logging of all tool invocations and file operations to compensate.

Agents adapt: Modern LLMs are smart enough to work within constraints. When an agent can’t execute a command, it usually finds an allowed alternative or asks for help.

The blast radius is contained: We’ve had agents attempt to delete files, run infinite loops, and make thousands of API calls. The sandbox caught all of them.

Compliance teams love it: Auditors are much happier when you can show them the exact subset of files an AI agent can access, rather than “everything the developer can access.”

AI Agent Security Checklist: Implementation Guide

If you’re building or deploying AI coding agents, here’s my recommended security checklist:

  1. Filesystem isolation: Use containers or VMs with explicit volume mounts
  2. Network segmentation: Restrict network access to only necessary endpoints
  3. Tool allowlisting: Whitelist specific commands and validate arguments
  4. Resource limits: Enforce CPU, memory, and storage quotas
  5. Audit logging: Log all tool executions and file modifications
  6. Ephemeral environments: Destroy containers after each session
  7. Least privilege: Run with minimal capabilities and non-root user
  8. Secret management: Never pass secrets via environment variables; use secret management services
  9. Timeout enforcement: Set maximum execution times for all operations
  10. Regular security reviews: Audit allowlists and policies quarterly

Future-Proof AI Agent Isolation with WebAssembly

Looking ahead, I’m excited about WebAssembly Component Model as the next evolution in agent sandboxing. WASM provides:

  • Capability-based security model (no ambient authority)
  • Near-native performance
  • Language-agnostic implementation
  • Fine-grained resource control

I’ve started experimenting with running AI agent tools as WASM components with wasmtime, and the early results are promising. It’s like containers, but with microsecond startup times and even stronger isolation guarantees.

Conclusion

AI coding agents are powerful tools, but only if we can trust them. Container isolation, tooling allowlists, and network segmentation transform AI agents from security liabilities into production-ready automation.

The overhead is minimal. The security benefits are substantial. And the peace of mind knowing your AI agent can’t accidentally rm -rf / your production database? Priceless.

Start with Docker containers and a simple allowlist. Graduate to Kubernetes with gVisor when you need scale. And keep an eye on WebAssembly for the next generation of agent isolation.

Your security team will thank you. Your compliance auditors will thank you. And your future self—the one who doesn’t have to explain how an AI agent deleted production data—will definitely thank you.

Found this helpful? Share it with others: