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

---
name: implementer
author:
  name: implementer-bot
  email: implementer@example.com   # sets the agent's git author identity
forge-accounts:
  project-gitea:                    # a named forge this agent can call
    url: https://git.example.com/api/v1
    auth:
      type: token
      token_secret: BOT_BOTTLE_FORGE_TOKEN   # host env var — never seen by the agent
---

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:
  repos:
    project:
      url: ssh://git@git.example.com/acme/project.git
      forge: project-gitea    # use the agent's forge account for API calls

egress:
  routes:
    # 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. The agent's identity signs its
commits; git-gate carries pushes to the project repo, and its forge
account reaches the Gitea API through the proxy — the bottle never holds
the token.
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.