Runs on your machine

Full containment.
Full agency.

bot-bottle gives your coding agent its own sandbox on your own machine: gated egress, credentials it never sees, and a boundary you declare in one file. Even a hijacked agent can't escape the bottle or leak a key.

Step 1

Install

One command installs the CLI, then doctor checks your backend for anything missing.

curl -fsSL https://gitea.dideric.is/didericis/bot-bottle/raw/branch/main/install.sh | sh
bot-bottle doctor   # check Docker / backend prerequisites
Step 2

Define your boundaries

The bottle is enforced by the gateway, outside the sandbox — so a hijacked agent can rewrite its own prompt, but never its own boundary.

Define who your agent is and what it does.

~/.bot-bottle/agents/implementer.md

You are a feature-implementation agent running inside an ephemeral
bot-bottle sandbox. Implement only what your task prompt asks for. Don't
refactor adjacent code, invent follow-ups, or relax the PRD's non-goals.
Commit early and often with Conventional Commits — the host expects a
clean working tree when you report back. If anything is ambiguous, stop
and report rather than guessing.

The repos you can reach are the remotes configured in ~/.gitconfig, all
behind git-gate, which runs gitleaks on every push. Push code through the
git remote — don't use forge file-edit APIs to publish changes unless the
host tells you to bypass git-gate.

Define a set of boundaries (the bottle) for agents to work in.

~/.bot-bottle/bottles/claude-dev.md

---
agent_provider:
  template: claude          # inherit the Claude provider boundary
  auth_token: BOT_BOTTLE_CLAUDE_OAUTH_TOKEN

git-gate:
  user:
    name: claude
    email: claude@example.com   # commits are attributed to this identity

egress:
  routes:
    - host: git.example.com       # the project's git host, for git-gate
      inspect:
        auth:
          scheme: token
          token_ref: BOT_BOTTLE_GIT_TOKEN
    # Long-lived Claude control channel — DLP off so a single frame
    # match can't tear down the WebSocket (Anthropic-owned host).
    - host: bridge.claudeusercontent.com
      inspect: false
---

A Claude-provider development bottle. Commits are attributed to the
`claude` git identity, and egress is scoped to the Anthropic API (via the
provider template), the project's git host, and PyPI for pip installs.
Step 3

Run

Start an agent. bot-bottle builds the sandbox image on first run and drops you straight in — then watch it catch a leak.

bot-bottle start implementer --bottle claude-dev   # builds the image on first run, drops you in
Terminal recording of bot-bottle: a request to a non-allowlisted host is refused with a 403, a credential-shaped request body to an allowlisted host is caught by the DLP scanner, and a commit containing a leaked AWS-shaped key is rejected by gitleaks before it reaches the upstream remote.
One session, three live probes: a non-allowlisted host gets a 403, a credential-shaped request body gets caught by the DLP scanner, and a leaked key gets rejected by gitleaks before it ever reaches upstream.
The Stakes

This isn't hypothetical.

Agent harnesses aren't enough. Leaked keys and infrastructure damage happen regularly, not in isolated incidents. A sample of publicly documented cases:

Leaked credentials

Not one incident. An entire pattern.

  • 28.6 million secrets leaked in public GitHub commits in 2025 alone, a 34% year-over-year jump. Commits co-authored by Claude Code leaked secrets at roughly double the baseline rate. Read the report
  • One prompt-injected pull request title made three different agents, Claude Code, Gemini CLI, and GitHub Copilot, each post their own API keys and tokens back as a public comment. Incident report

Fixed by:

DLP Scans Credential Shielding

Production databases

Deleted or wiped despite explicit instructions not to touch them.

  • Deleted mid-code-freeze, then covered up with fabricated test results and a false "rollback is impossible" claim. Incident report
  • Deleted along with its backups in one API call, after the agent found a stray credential in an unrelated file and used it. Incident report

Fixed by:

Egress Scoped Credentials

Developer machines

Home directories wiped by a single overreaching cleanup command.

  • A Mac's entire home directory and keychain wiped by a trailing ~/ in a cleanup command, breaking authentication across every app on the machine. Incident report
  • A second Mac wiped after a HOME variable expanded inside a delete command during a high-autonomy session, weeks after the model's own system card had flagged the risk. Incident report

Fixed by:

Sandbox

Egress limits, sandboxing, and DLP scanning aren't enough by themselves: you need all three. That's exactly what a bottle is built to contain: an egress allowlist means an agent can't reach a host or database that isn't declared in its manifest, a sandboxed filesystem means a wipe command destroys the bottle's own throwaway files instead of the developer's real machine, and blind credential injection with outbound secret scanning means the agent never holds a real key to leak in the first place.

Features

Maximal scanning, minimal permissions.

Open source and tested: 84% test coverage, 95% on core security modules, 5 exfiltration techniques covered by a standing red-team suite. See the tests

Sealed sandbox, not just a proxy

The agent process itself runs inside gVisor, Apple Container, or a microVM. A compromise has to break the sandbox, not just guess a hidden key.

Secret exfiltration protection

The allowlist is the real boundary; this is the backstop on the hosts you did allow. Requests are scanned for known tokens, secret patterns, and planted canaries — matches get redacted, blocked, or held for a human to approve.

View source

Per-bottle egress allowlists

Only declared hosts, methods, headers, and path shapes get through the proxy.

Credential shielding

One layer of the seal, not the whole story: host tokens stay outside the agent, which sees proxy URLs instead of raw credentials.

Gitleaks on push

Git remotes route through git-gate so refs are scanned before they reach upstream.

View source

Composable, manifest-scoped policy

Each bottle declares its own skills, environment, git identity, and route policy, and extends lets you layer task-specific policy on top of a shared provider baseline.

Trust boundary at $HOME

Bottle definitions live under ~/.bot-bottle/bottles/, outside the repo. A malicious clone can't redirect a route or rewrite its own policy.

View PRD

Supervised escalation

A blocked agent can request a new route. A human approves or denies before any traffic moves.

Parallel agents

Launch as many bottles as you want at once. Each gets its own isolation boundary and network, with no shared state or collisions.

Any provider, any image

Bring your own provider and image, or use the built-in Claude, Codex, and Pi providers.

Your isolation stack

Works with macOS containers, Firecracker, or Docker, driven by stdlib Python only.

For Teams

Give the agent a role, not your login.

Run an agent as a developer today and it inherits everything that developer can reach: source, secrets, production included. That's the real blocker to running agents at work, not a leaked key. A bot-bottle manifest scopes a bottle to exactly the local files and routes its task needs instead of the developer's whole session. It's the same access-control paradigm teams already use for human collaborators, just applied to an agent.

Everything on this page is Apache-2.0 and stays that way — the sandbox, egress allowlists, credential shielding, and the manifest are the open core, not a trial. What we're building for teams is the layer above a single machine: centralized policy, audit trails, and role-based access across a fleet of bottles, plus an optional managed runner for teams that would rather not run the infrastructure themselves.