Claude Code
Run Claude Code inside an AgentVisor sandbox with policy-enforced outbound HTTP and host-side credential brokering.
Difficulty: Expert
This example uses agentvisor exec mode. Unlike serve and run, exec mode bridges your terminal directly into the sandbox without Temporal workflows or an HTTP API. All HTTP proxy, MCP, A2A, and store features remain available.
What You'll Learn
- Using
agentvisor execto run Claude Code (or any AI coding tool) inside an isolated sandbox - Providing a custom
Dockerfileto install Node.js and theclaudeCLI into the minimal guest image - Configuring proxy credential brokering so the host-side
ANTHROPIC_API_KEYnever enters the guest verbatim - Writing an MPE policy that restricts outbound HTTP to only
api.anthropic.com - Why Claude Code's telemetry requests are denied — and why that's the correct behavior
Security Model
The sandbox enforces the same defense-in-depth as serve mode:
- HTTP proxy: All outbound HTTP/HTTPS is intercepted by the policy engine. Claude Code can only reach explicitly allowed endpoints (
api.anthropic.com) - Credential substitution: A symbolic token is injected into the guest; the real
ANTHROPIC_API_KEYstays on the host and is substituted by the proxy only for allowed destinations - Network isolation: No direct outbound connections — all traffic goes through the proxy
- Syscall filtering: gVisor's application kernel (when
--sandbox=gvisor)
Telemetry and auto-update requests from Claude Code (statsig.anthropic.com, api.github.com, etc.) are denied by policy. This is intentional — those domains are not in the allowlist.
Project Structure
claude-code/
├── mav-agent-config.yaml # Interactive provider + claude command
├── agentvisor.yaml # Proxy credential-broker (must be in cwd or config dir)
├── Dockerfile # Installs Node.js 18 + git + claude CLI
├── .dockerignore # Excludes policies/, *.md, agentvisor.yaml
└── policies/
├── domain.yml # MPE PolicyDomain — Anthropic API only
└── test.yml # Policy test cases
mav-agent-config.yaml
framework:
provider: interactive
command: ["claude", "--dangerously-skip-permissions"]
env:
TERM: xterm-256color
--dangerously-skip-permissions bypasses Claude Code's built-in per-command consent prompts. The MPE policy — not Claude Code's internal model — is the enforcement boundary inside the sandbox.
agentvisor.yaml
proxy:
credentials:
- name: anthropic-key
guest_env_var: ANTHROPIC_API_KEY
destinations:
- "api\\.anthropic\\.com"
resolver:
type: bearer_token
source: env
env_var: ANTHROPIC_API_KEY
The destinations field is required — it restricts credential substitution to api.anthropic.com only. Even if another host were somehow allowed by policy, the proxy would not inject the real API key for it.
Dockerfile
The base agentvisor-guest:*-minimal image does not include Node.js or the claude CLI. It is built on ubi9/ubi-minimal (Red Hat UBI 9), so the package manager is microdnf. The custom Dockerfile layers Node.js 18 and claude in:
FROM {{.Image}}
# Node.js 18 LTS (meets Claude Code's >=18 requirement) + git
RUN microdnf install -y git nodejs npm && microdnf clean all
RUN npm install -g @anthropic-ai/claude-code \
&& npm cache clean --force
COPY agent /app/agent
git is included because Claude Code requires it for many of its editing and diff workflows.
policies/domain.yml (highlights)
# Allow the Anthropic inference API and the Claude subscription/OAuth platform
annotations:
- name: "allowed_patterns"
value:
- "^api\\.anthropic\\.com(/.*)?$"
- "^platform\\.claude\\.com(/.*)?$"
- name: "blocked_patterns"
value:
- ".*\\.internal$"
- ".*\\.local$"
- "metadata\\.google\\..*"
- "169\\.254\\..*"
All internal networks (10.x, 192.168.x, 127.x, 0.0.0.0, localhost) are blocked via hardcoded checks in the Rego policy regardless of the annotations above.
Setup
agentvisor template create interactive/claude-code
cd claude-code
Export your Anthropic API key on the host (never put the real key inside the sandbox or in .env):
export ANTHROPIC_API_KEY=sk-ant-...
Run
Direct exec (development)
The CLI searches for agentvisor.yaml in the current working directory, $HOME/.config/agentvisor, or /etc/agentvisor. agentvisor template create scaffolds agentvisor.yaml into the project root, so running from that directory just works:
agentvisor exec .
Without Docker (no sandbox isolation, for local debugging):
agentvisor exec . --sandbox=none
With gVisor for stronger isolation (Linux only):
agentvisor exec . --sandbox=gvisor
Build and run interactively (production)
# Build the OCI image (embeds Node.js, claude CLI, and policies)
agentvisor build . -t claude-code-sandbox:latest
# Run interactively with Docker + gVisor
docker run -it --rm \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/agent/policies/domain.yml \
-e ANTHROPIC_API_KEY \
claude-code-sandbox:latest \
exec /agent
Logging
Exec mode is silent by default — no logs appear on the terminal, keeping the interactive session clean:
# Write logs to a file (terminal stays clean)
agentvisor exec . --log-file /tmp/agentvisor.log
# Print logs to stderr
agentvisor exec . --verbose
Available Downcalls
| Feature | Available |
|---|---|
| HTTP proxy (with credential substitution) | Yes |
| MCP gateway | Yes |
| A2A gateway | Yes |
| Key-value store | Yes |
| Log forwarding | Yes |
| Checkpointing | No |
| SSE streaming | No |
Checkpointing and SSE streaming require Temporal workflows and the HTTP API, which exec mode intentionally omits.
Policy Highlights
Two domains are in the allowlist — the Anthropic inference API and the Claude subscription/OAuth platform:
- name: "allowed_patterns"
value:
- "^api\\.anthropic\\.com(/.*)?$"
- "^platform\\.claude\\.com(/.*)?$"
Claude Code may attempt to contact telemetry or update endpoints on startup. Those requests will be denied — that is expected and intentional. Claude Code falls back gracefully.
Validate the policy without running the agent:
mpe test decisions -d ./policies/domain.yml -i ./policies/test.yml
Customizing the Environment
Place a Dockerfile in the example directory to install additional tools into the sandbox:
FROM {{.Image}}
# ... existing Node.js + claude install ...
# Add extra tools (microdnf is the package manager in UBI 9 minimal):
RUN microdnf install -y ripgrep && microdnf clean all
See exec reference — Customizing the Sandbox Environment for the full list of template variables and options.
Troubleshooting
Terminal appears corrupted after exit
If the sandbox process exits abnormally, run reset to restore terminal settings.
Policy denied errors
Check the policy is allowing the endpoint your session needs:
AGENTVISOR_LOG_LEVEL=debug agentvisor exec . --verbose
For development only, bypass authorization entirely:
AGENTVISOR_AUTHZ_TYPE=allowall agentvisor exec .
Never use AGENTVISOR_AUTHZ_TYPE=allowall in production.
See Also
- Simple Shell — basic interactive shell, no credential brokering
- Pentest Agent — LangGraph agent using the Anthropic API in serve mode
- agentvisor exec CLI reference
- Sandbox Modes