Skip to content

docs: add agent execution sandboxing proposal - #70

Open
AIWithShrey wants to merge 4 commits into
mainfrom
docs/proposal-agent-execution-sandboxing
Open

AIWithShrey wants to merge 4 commits into
mainfrom
docs/proposal-agent-execution-sandboxing

Conversation

@AIWithShrey

Copy link
Copy Markdown
Collaborator

What

Adds a Draft design proposal (docs/dev/PROPOSAL_AGENT_SANDBOXING.md): opt-in sandboxing for agent execution, so untrusted MCP tools — LLM-selected uvx/npx code fetched at runtime — can't expose LLM credentials, ServiceAccount tokens, and API keys across workflows.

Why

Today the agent-executor pod (and the runner Job for MCPToolCall steps) runs LLM-chosen, runtime-fetched code with no kernel-level isolation — only restricted-PSS hardening — beside the ServiceAccount token, the agent-executor TLS key, and forwarded LLM credentials. This proposal documents the problem and a phased path to close it.

Approach (phased)

  • Phase 1 — native runtimeClassName (gVisor/Kata): the cheap, reversible step shippable today (Helm value + controller plumbing, default off). Provides kernel/node-breakout isolation and installs the gVisor prerequisite Phase 2 needs anyway.
  • Phase 2 — kubernetes-sigs/agent-sandbox (executionMode: sandbox): per-execution pods (+ warm pool) that close cross-workflow credential exposure. Already named as a future enhancement in DESIGN.md.
  • Agent Substrate: evaluated and deferred — v0.0.0, does not compose with the current exec path as-is; the ExternalAgentRef→A2A path is noted as a low-risk interop experiment.

Scope

Docs-only (Draft proposal). No code changes; the "Files to Change" section scopes the Phase 1 implementation for a follow-up PR.

Isolation scope (no overclaim)

The proposal states explicitly that Phase 1 gVisor is node/kernel isolation, not intra-pod: the untrusted tool still shares its pod with credentials until Phase 2 (per-execution pods) combined with per-step ServiceAccounts.

Propose opt-in kernel isolation for agent/MCP-tool execution. Phase 1 adds
native runtimeClassName (gVisor/Kata) on the agent-executor and runner Job
(Helm-gated, default off); Phase 2 promotes to kubernetes-sigs/agent-sandbox
per-execution pods. Agent Substrate is evaluated and deferred (v0.0.0).
Draft in docs/dev.
@AIWithShrey
AIWithShrey requested review from JimBugwadia and patelrit and a balanced review from Copilot August 28, 2026 14:21
@AIWithShrey AIWithShrey self-assigned this Aug 28, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a draft proposal for phased sandboxing of untrusted MCP execution.

Changes:

  • Documents current execution risks and isolation limits.
  • Proposes runtimeClassName followed by per-execution sandboxes.
  • Outlines implementation, testing, and rollout.
Suppressed comments (4)

docs/dev/PROPOSAL_AGENT_SANDBOXING.md:34

  • Agent.spec.executorImage is not consumed by the current shared-service execution path; repository references are limited to the API and documentation. Listing it as an effective image knob could cause operators to set a field that does not enable uvx/npx in the agent-executor pod. Identify the shared Deployment's Helm image setting instead and explicitly note that the CRD field is currently inactive.
for `AgentRef` (agent-executor) it is the agent-executor image (`agentExecutorImage` / the Agent
`executorImage` field); for direct `MCPToolCall` (runner Job) it is the runner image
(`RunnerImage`, or a per-run `spec.execution.job.image` override) — `executorImage` does not

docs/dev/PROPOSAL_AGENT_SANDBOXING.md:69

  • A per-execution Sandbox does not close the intra-pod credential gap: the MCP subprocess still shares the execution environment with the credentials that execution needs. It limits cross-workflow exposure by removing the long-lived shared executor, while separating or minimizing the current execution's credentials requires additional design.
**Pros**: Standards-track, stable-API path (unlike a v0.0.0 project). Per-execution isolation
closes the intra-pod gap — the untrusted tool no longer co-resides with long-lived shared
credentials. Warm pool addresses cold-start; already anticipated by OttoFlow's `executionMode`
design.  

docs/dev/PROPOSAL_AGENT_SANDBOXING.md:127

  • This states breakout prevention as a guarantee, but gVisor only reduces the host-kernel attack surface and adds a stronger isolation boundary; it can still have escape vulnerabilities. Since the proposal explicitly aims not to overclaim, describe the risk reduction rather than saying untrusted code “cannot” reach the host.
gVisor via `runtimeClassName` provides node/kernel isolation: it contains a container breakout
so untrusted code cannot exploit the host kernel to reach the node or other workloads. It does

docs/dev/PROPOSAL_AGENT_SANDBOXING.md:131

  • Per-step identity limits the privilege and scope of a token that remains reachable; it does not close intra-pod credential access, and per-execution isolation only prevents cross-execution exposure. Rephrase this as containment/minimization rather than claiming the residual gap is closed.
NOT provide intra-pod isolation: an untrusted tool still shares its pod with the ServiceAccount
token, the TLS key, and forwarded LLM credentials, and can read them. Closing that residual gap
requires per-execution isolation (Option B) combined with per-step identity (see
`docs/dev/PROPOSAL_PER_STEP_SA.md`). Phase 1 is a real and worthwhile reduction in blast radius,

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread docs/dev/PROPOSAL_AGENT_SANDBOXING.md Outdated
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants