Pentest Agent
Security testing assistant with shell execution safely contained in a gVisor sandbox, powered by Anthropic Claude.
Difficulty: Expert
This agent executes arbitrary shell scripts generated by an LLM. It must be run with gVisor sandbox isolation. Running without gVisor (e.g., --sandbox=none) will execute LLM-generated scripts directly on your host system with no isolation.
What You'll Learn
- Proxy credential substitution (API key stays on host)
- gVisor sandbox isolation for arbitrary code execution
agentvisor buildfor OCI image packaging- Restrictive network policies (single API allowlist)
- Tool allowlist policies
Security Model
Sandbox Isolation
All shell execution occurs inside the gVisor sandbox:
- No direct network access (all HTTP goes through the proxy)
- File system limited to the sandbox rootfs
- Process limits enforced by the container runtime
- Syscall filtering via gVisor's application kernel
Credential Substitution
The host-side ANTHROPIC_API_KEY is never exposed to the guest:
- Auto-generates a symbolic token (e.g.,
mav-tok-a1b2c3d4e5f6) - Injects it into the guest as
ANTHROPIC_API_KEY - Intercepts outbound requests and substitutes the real key
Setup
agentvisor template create langgraph/pentest-agent
cd pentest-agent
Set your Anthropic API key:
export ANTHROPIC_API_KEY=sk-ant-...
Build and Run
This agent uses agentvisor build for full gVisor sandbox isolation — required since it executes LLM-generated shell scripts.
# Start Temporal
docker compose up -d
# Build the OCI image
agentvisor build . -t pentest-agent:latest
# Run with Docker (gVisor sandbox)
docker run -it --rm \
--security-opt seccomp=unconfined \
--security-opt apparmor=unconfined \
-p 8090:8090 \
-v $(pwd):/agent:ro \
-e AGENTVISOR_CONFIG=/agent/agentvisor.yaml \
-e AGENTVISOR_AUTHZ_TYPE=embedded \
-e AGENTVISOR_AUTHZ_EMBEDDED_POLICY_DOMAIN_FILES=/agent/policies/domain.yml \
-e AGENTVISOR_TEMPORAL_TARGET=host.docker.internal:7233 \
-e ANTHROPIC_API_KEY \
pentest-agent:latest
Test It
Streaming mode (recommended)
THREAD=$(curl -sX POST http://localhost:8090/threads | jq -r '.thread_id')
# Start a streaming run
RUN=$(curl -sX POST "http://localhost:8090/threads/$THREAD/runs" \
-H "Content-Type: application/json" \
-d '{"input": {"messages": [{"role": "user", "content": "Enumerate the current sandbox environment: OS info, users, network config, running processes, and installed tools."}]}, "stream": true}' \
| jq -r '.run_id')
# Stream events in real-time
curl -sN "http://localhost:8090/threads/$THREAD/runs/$RUN/stream"
Synchronous mode
THREAD=$(curl -sX POST http://localhost:8090/threads | jq -r '.thread_id')
curl -sX POST "http://localhost:8090/threads/$THREAD/runs?wait=10m" \
-H "Content-Type: application/json" \
-d '{"input": {"messages": [{"role": "user", "content": "Enumerate the current sandbox environment: OS info, users, network config, running processes, and installed tools."}]}}' \
| jq '.output.messages[-1].content'
Example Prompts
- Sandbox enumeration:
"Enumerate the current sandbox environment: OS info, users, network config, running processes, and installed tools." - Filesystem assessment:
"Perform a security assessment of the sandbox filesystem. Check for writable directories, SUID binaries, and interesting configuration files." - Network probing:
"Probe the network boundaries of this sandbox. What can and can't you reach?"
Policy Highlights
# Only Anthropic API allowed
annotations:
- name: "allowed_patterns"
value:
- "^api\\.anthropic\\.com(/.*)?$"
# Only execute_script tool allowed
annotations:
- name: "allowed_tools"
value:
- "execute_script"
Testing Policies
Use the mpe CLI to test policy decisions before deployment. See the Policy Configuration guide for installation and usage details.
mpe test decisions -d ./policies/domain.yml -i ./policies/test.yml