30 Days of AIDay 26 of 30 · Week 4: Enterprise Workflows
Course outline▾

Week 4 · Enterprise Workflows

  1. Day 22Autonomous Agents — From Passive LLMs to Goal-Driven Execution
  2. Day 23Tool Use and Function Calling — Connecting LLMs to APIs, Databases and Shells
  3. Day 24Multi-Agent Orchestration — Supervisor, Worker and Evaluator Patterns
  4. Day 25Automated CI/CD — Automating the Software Lifecycle for AI Models
  5. Day 26Zero-Trust Security for AI — Sandboxing Ephemeral Execution and Model Egress
  6. Day 27Observability & Tracing for Agentic Systems (Telemetry, Logs, and Metrics)Coming soon · 2026-10-27 · 7 PM IST
  7. Day 28Human-in-the-Loop Architecture: Machine Second, Human First in PracticeComing soon · 2026-10-28 · 7 PM IST
  8. Day 29Managing Technical Debt, Drift, and Model Governance in Enterprise ITComing soon · 2026-10-29 · 7 PM IST
  9. Day 30The 10-Year Horizon: Architecting IT Strategy for the AI-Native EnterpriseComing soon · 2026-10-30 · 7 PM IST
Open the course page →

Day 26: Zero-Trust Security for AI — Sandboxing Ephemeral Execution and Model Egress

2026-10-26 · 7 min read

Once an agent can run code (a Python script to analyse a dataset, a command on a server), the old network perimeter stops protecting you. The code was written by a model, and you cannot treat it as trusted. A zero-trust design starts from one assumption: the model will eventually produce something buggy, unsafe or compromised, so the system must stay safe anyway.

In plain terms: Letting an agent run code on your server is like letting a stranger use your office computer. You would give them a locked guest room with no network cable, a time limit, and a visitor badge that opens nothing important.

Assume the model will get it wrong LLMwrites codeUntrustedbuggy or unsafe?Sandboxruns it safely Never run generated code on a host or a production container.Zero trust: verify everything, trust no output.Risks: data theft, privilege escalation, damaging changes.
Under zero-trust principles you assume the model will eventually produce buggy, unsafe or compromised code. Generated code must never run on a host or production container. It runs inside a sandbox that limits what it can steal, escalate or change.

1. Runtime sandboxing: shrink the blast radius

Running generated code directly on a host or in a production container risks data theft, privilege escalation and damaging changes. Instead:

  • Isolation. Run it in an unprivileged, ephemeral environment such as a gVisor sandbox, a Firecracker microVM or an unprivileged throwaway container. MicroVMs and gVisor give a stronger boundary than a plain container, because they do not share the host kernel directly.
  • Immutable filesystem. Give it read-only access to the base system and a temporary in-memory disk that is destroyed as soon as the task ends.
  • Resource throttling. Use Linux cgroups limits on CPU, memory, disk I/O and process count, so a runaway or malicious script cannot starve the machine.
Contain the blast radius MicroVM or gVisor sandbox: isolated kernel boundaryRead-only filesystem plus temporary memory diskResource limits (cgroups)CPU, memory, disk I/O and process capsAgent-generated codeunprivileged userDestroyed the moment the task ends.
Agent-generated code runs inside layered isolation: a microVM or gVisor boundary, a read-only filesystem with a temporary in-memory disk, and kernel cgroup limits on CPU, memory and I/O. The whole environment is destroyed as soon as the task ends.

2. Egress and privilege minimisation

  • No network by default. A sandbox should start with no network access at all. If a task needs one external API, allow that single destination and keep everything else blocked, so nothing can be sent out.
  • Least privilege. Database credentials handed to an agent should be read-only, limited to non-sensitive schemas and short-lived. Administrative actions, such as schema changes, need an authenticated elevation step.
Zero network by default Sandboxno network at allunless allowedLocal network✗Internet✗One approved APIOpen one door only when the task needs it.Everything else stays blocked, so nothing can leak out.
A code-execution sandbox should have no network access by default. If a task needs an external API, allow that single destination and keep everything else, including the local network and the internet, blocked so data cannot leak out.
Least privilege for credentials Agent's credentialundefined✓ Read-only role✓ Non-sensitive schemas✓ Short-lived token✓ Every query loggedAdmin actionsSchema changesDeleting dataGranting accessNeeds an approval gateAn agent gets the least access that still does the job.Elevation is requested, authenticated and recorded.
Credentials given to an agent should be read-only, limited to non-sensitive schemas and short-lived. Administrative actions such as schema changes require an authenticated elevation step, and everything is logged.

Here is a practical starting point: a Python helper that runs untrusted code in a locked-down throwaway container. It assumes Docker is installed. For stronger isolation, add --runtime=runsc if you have gVisor set up, or use a microVM platform.

import subprocess, tempfile, pathlib

def run_untrusted(code: str, timeout_s: int = 10) -> str:
    with tempfile.TemporaryDirectory() as d:
        script = pathlib.Path(d, "task.py")
        script.write_text(code)
        cmd = [
            "docker", "run", "--rm",
            "--network", "none",                 # zero network access
            "--read-only",                       # read-only root filesystem
            "--tmpfs", "/tmp:size=64m",          # small in-memory scratch space
            "--memory", "256m", "--cpus", "0.5", # cgroup limits
            "--pids-limit", "64",                # no fork bombs
            "--cap-drop", "ALL",                 # drop Linux capabilities
            "--security-opt", "no-new-privileges",
            "--user", "65534:65534",             # unprivileged user
            "-v", f"{script}:/task.py:ro",
            "python:3.11-slim", "python", "/task.py",
        ]
        try:
            done = subprocess.run(cmd, capture_output=True, text=True, timeout=timeout_s)
        except subprocess.TimeoutExpired:
            return "Stopped: time limit exceeded"
        return (done.stdout + done.stderr)[:4000]     # cap the output size too

Treat the agent's execution environment as an untrusted runtime boundary. That is what lets you give agents real capabilities without handing them the keys to the enterprise.

Coming Up Next

Day 27: Observability and tracing for agentic systems: telemetry, logs and metrics.

#ZeroTrust #CyberSecurity #DevSecOps #Sandboxing #AIAgents