Skip to main content

Pentest Agent

Security testing assistant with shell execution safely contained in a gVisor sandbox, powered by Anthropic Claude.

Difficulty: Expert

warning

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 build for 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:

  1. Auto-generates a symbolic token (e.g., mav-tok-a1b2c3d4e5f6)
  2. Injects it into the guest as ANTHROPIC_API_KEY
  3. 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

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