Let a coding agent run wild on your Mac, without trusting it.
drydock runs Claude Code, OpenAI Codex, or any OpenAI-compatible
model (Gemini, OpenRouter, local) full-throttle on your own repos, on your
own Mac — no permission prompts, no babysitting. Each task runs sealed in a
throwaway VM. The only thing that ever comes back is a git diff, and nothing
reaches your real code until you approve it.
- It never gets your key. Your real API key stays on the host; the agent only ever sees a short-lived, budget-scoped token (spend overshoot is bounded to one in-flight request by default).
- It can't smuggle anything out. The internet is deny-by-default: no exfiltrating your code, no calling home (you allow the package registries it needs, nothing else).
- Nothing touches your repo until you say so. You read the diff and approve
it before it ever reaches
origin.
Most agent tooling tries to keep the agent well-behaved: permission prompts, output filters, policy. drydock takes the opposite stance: contain the blast radius. A hostile agent — a poisoned repo, a malicious dependency, a prompt injection that turns a fetched URL into a shell command — can't reach your key, your filesystem, your push credentials, or the open internet, regardless of what it tries.
Don't take the threat model's word for it. Every green above is a real go test red-team case that runs the actual attack and asserts it fails. Reproduce them yourself: see Prove it yourself.
Docs · Threat model · Website · Roadmap
- Works end-to-end. The full task lifecycle runs (submit → isolated VM → gated diff → push), and drydock ships through a Homebrew tap.
- Containment claims are tested, not asserted. Every claim in the threat model is a red-team test that runs the real attack and asserts it fails. Security-sensitive changes are developed exploit-first and adversarially reviewed.
- Still pre-1.0. Only
mainis supported, behavior and config can change between minor versions, and it has not been hardened by wide real-world use. - No third-party security audit yet. The security model is written down in detail in the threat model — read it and decide for yourself before trusting it.
- Hard requirement: macOS 26+ on Apple silicon. drydock runs on Apple's
containerruntime (1.x, validated through 1.1.0), which ships nowhere else.
- For: unattended or batch agent runs you don't want to babysit, and anyone who'd rather contain an agent than trust it to behave.
- Not for: interactive sessions where you're watching every step (that's overkill), or anything off macOS 26+ Apple silicon (it won't run).
1. Check you're eligible. drydock runs locally, and Apple's container
runtime needs macOS 26+ on Apple silicon:
[ "$(uname -m)" = arm64 ] && [ "$(sw_vers -productVersion | cut -d. -f1)" -ge 26 ] \
&& echo "eligible" || echo "not yet, needs macOS 26+ on Apple silicon"2. Install. Sets up the runtime, squid, and ~/.drydock:
brew install sricola/drydock/drydock
drydock setup3. Give it a credential and start. A vendor API key works:
export ANTHROPIC_API_KEY=sk-ant-...
drydock start…or skip keys entirely and reuse a plan you already pay for:
drydock auth claude # Claude Pro/Max → anthropic_auth: subscription
drydock auth codex # ChatGPT → openai_auth: subscription
drydock start4. Submit your first sandboxed task (in another shell):
drydock submit --repo git@github.com:you/repo \
--instruction "Add a one-line comment to README.md."
drydock review <id> # read the diff, then approve or denyThat's the whole loop: the agent runs sealed, hands back a git diff, and
nothing reaches your repo until you approve it. The full walkthrough is in the
Quickstart.
A few things you'll probably want next:
- Run it unattended (start at login, restart on crash):
drydock daemon install— see Run unattended. - Bound your spend: set
aggregate_budget_usdto cap cross-task spend (subscription mode is bounded bytask_max_requestsinstead). - See run metrics across tasks:
drydock stats [--since 30d] [--by agent|vendor|repo|day|week] [--json]aggregates outcome rates, duration and gate-wait percentiles, spend, and egress-widen frequency straight from the audit dir. - Build from source:
brew install go, clone, thenmake install && drydock init.
Full operator docs live at sricola.github.io/drydock/docs:
- Quickstart: install to first task.
- Authentication: API key or subscription, Claude Code & Codex.
- Models: bring your own OpenAI-compatible endpoint (Gemini, OpenRouter, local).
- Submitting tasks:
drydock submit, the approval gate, flags, scripting. - Web UI: the board, approval gate, and history in a local browser app.
- Egress & widening: the allowlist and per-task widening.
- Configuration:
config.yamland env overrides. - Security defaults: the shipped financial and containment bounds, generated from code.
- Troubleshooting:
drydock doctorand common failures. - Threat model: what drydock defends, and what it doesn't.
You don't have to trust the threat model — run the attacks. drydock redteam
boots throwaway VMs and runs the real red-team cases behind the security
claims (key isolation, deny-by-default egress, VM teardown) and prints a
pass/fail table. No API key, no spend, ~5 minutes.
drydock redteam # live containment attacks
make demo VM=1 # …or watch all seven, including live VM isolationCodebase layout, build/test/CI, and known gaps are in
CONTRIBUTING.md. Security reporting and documented
residuals are in SECURITY.md.