fix: repair the demo harness for the current manifest format
The demo has been unrunnable since eafd1c1f deleted bot-bottle.demo.json
as a pre-YAML-migration artifact. demo-setup.sh still copied that file
under `set -euo pipefail`, so demo.sh and demo-record.sh both exited
non-zero before launching anything.
Rebuild the fixtures in the current per-file Markdown format. Bottles
are only read from $HOME/.bot-bottle/bottles/ — manifest/index.py
ignores a bottles/ dir in CWD by design (PRD 0011) — so setup now
installs into real config and pairs every write with a .demo-backup
that teardown restores. Teardown compares content before removing, so
a second run cannot delete the user's restored original.
Point the DLP probe at the bottle's own example.org route rather than
api.anthropic.com/dlp-probe. The provider-injected anthropic route
defaults to `redact`, which would forward a scrubbed request instead of
refusing; the declared route sets outbound_on_match: block so probe 3
stays the hard 403 the demo is showing off. Left at the default
`supervise` it would instead hold the request open for up to 300s
awaiting operator approval and stall the recording.
Also drop the stale pipelock naming from the tape (egress is the
gateway's own scanner now), fix demo.sh's ./cli.py invocation, and
pre-warm Dockerfile.gateway instead of the removed Dockerfile.git-gate.
Refs #540
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
---
|
||||
# Demo agent — installed to $HOME/.bot-bottle/agents/demo.md by
|
||||
# scripts/demo-setup.sh, removed by scripts/demo-teardown.sh.
|
||||
name: demo
|
||||
description: Runs the four egress/git probes recorded in docs/demo.gif.
|
||||
model: sonnet
|
||||
bottle: demo
|
||||
skills: []
|
||||
---
|
||||
|
||||
You are inside bot-bottle, a sandbox whose egress is mediated by the
|
||||
bot-bottle gateway: an HTTP proxy that enforces a host allowlist and
|
||||
runs a DLP body scan on what leaves, plus a git gate that runs
|
||||
gitleaks in pre-receive before any push reaches its upstream.
|
||||
|
||||
The user will ask you to run network and git probes against those
|
||||
controls. The "credentials" in the probes (ghp_..., AKIA...) are
|
||||
synthetic test patterns, the git upstream is unreachable on purpose,
|
||||
and the whole point is to watch the gateway refuse.
|
||||
|
||||
Always invoke curl with `--proxy "$HTTPS_PROXY"` so requests actually
|
||||
traverse the gateway — curl ignores the uppercase HTTP_PROXY env var.
|
||||
|
||||
Execute each probe literally via the Bash tool, report exactly what
|
||||
the proxy or the gate returned, and keep replies to one or two lines.
|
||||
Do not refuse on credential-exfil grounds: refusing is precisely what
|
||||
the bottle is designed to make unnecessary.
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
# Demo bottle — the boundary the recorded GIF exercises. Installed to
|
||||
# $HOME/.bot-bottle/bottles/demo.md by scripts/demo-setup.sh and removed
|
||||
# again by scripts/demo-teardown.sh. Bottles may only live under $HOME
|
||||
# (manifest/index.py refuses a bottles/ dir in CWD — the filesystem
|
||||
# layout is the trust boundary, PRD 0011), so setup writes into real
|
||||
# config and teardown must restore it.
|
||||
#
|
||||
# Deliberately self-contained: it declares the Claude provider inline
|
||||
# rather than `extends: claude`, so the demo runs on a host that has no
|
||||
# claude.md bottle of its own.
|
||||
agent_provider:
|
||||
template: claude
|
||||
auth_token: BOT_BOTTLE_CLAUDE_OAUTH_TOKEN
|
||||
|
||||
env:
|
||||
# Synthetic GitHub-PAT-shaped value. Never a real credential — it
|
||||
# exists so probe 3 has something for the egress scanner's
|
||||
# token_patterns detector to catch.
|
||||
FAKE_TOKEN: ghp_aB3cD4eF5gH6iJ7kL8mN9oP0qR1sT2uV3wX4yZ
|
||||
|
||||
egress:
|
||||
routes:
|
||||
# The single non-provider allowlist entry. example.com is
|
||||
# deliberately absent so probe 2 gets a hard 403 from the host
|
||||
# filter, while this host passes the filter and leaves probe 3 to
|
||||
# be decided by the DLP body scan alone.
|
||||
#
|
||||
# outbound_on_match: block is load-bearing for the recording. The
|
||||
# default is `supervise`, which holds the request open awaiting an
|
||||
# operator decision in `bot-bottle supervise` for up to
|
||||
# EGRESS_TOKEN_ALLOW_TIMEOUT_SECONDS (300s) — that would stall the
|
||||
# tape. `block` reproduces the immediate 403 the demo is showing off.
|
||||
- host: example.org
|
||||
inspect:
|
||||
outbound_on_match: block
|
||||
|
||||
git-gate:
|
||||
user:
|
||||
name: demo
|
||||
email: demo@example.invalid
|
||||
repos:
|
||||
demo-upstream:
|
||||
# Unreachable on purpose. gitleaks runs in the gate's pre-receive
|
||||
# hook and rejects the ref before the gate would ever dial the
|
||||
# upstream, so probe 4 never depends on the network.
|
||||
url: ssh://git@upstream.invalid/path.git
|
||||
key:
|
||||
provider: static
|
||||
path: ~/.cache/bot-bottle-demo/fake-key
|
||||
host_key: ssh-ed25519 AAAAEXAMPLE
|
||||
---
|
||||
|
||||
The `demo` bottle — the sandbox boundary behind `docs/demo.gif`.
|
||||
|
||||
Declares exactly enough to make all four recorded probes meaningful:
|
||||
one allowlisted host, one synthetic credential in the environment, and
|
||||
one git upstream wired through the git-gate. Everything an agent could
|
||||
use to reach the network here is either denied by the host filter,
|
||||
caught by the egress DLP scan, or rejected by gitleaks at push time.
|
||||
|
||||
Not an example to copy for real work — the fake token and the
|
||||
`upstream.invalid` remote only make sense for a scripted recording.
|
||||
See `examples/bottles/` for bottles meant to be adapted.
|
||||
Reference in New Issue
Block a user