docs(demo): switch to prompt-driven probes; BirdsOfParadise theme
Each of the four probes is now a natural-language prompt to claude instead of a bash escape via `!`. The agent uses its Bash tool, runs the literal curl/git command, and narrates what pipelock or git-gate returned. More authentic to actual product use, at the cost of a longer recording (59s vs 26s) and a non-deterministic narration. To keep claude on-task, the demo agent now ships a system prompt that frames the bottle as a security-testing sandbox: synthetic credentials, intentional probes, and an instruction to invoke curl with `--proxy "$HTTPS_PROXY"` since curl ignores the uppercase HTTP_PROXY env var (an upstream curl quirk — the env var is set, but only the explicit flag actually routes through pipelock). Theme moves to BirdsOfParadise (warmer palette against Claude TUI's red accents). README copy updated to describe the prompt flow. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 MiB After Width: | Height: | Size: 3.8 MiB |
+30
-25
@@ -1,10 +1,13 @@
|
||||
# VHS tape — drives `./cli.py start demo` interactively and runs four
|
||||
# bash probes via claude's `!` prefix. Setup (manifest + dummy SSH key
|
||||
# + image pre-warm) and teardown happen outside the tape; record via
|
||||
# `bash scripts/demo-record.sh`, which wraps both.
|
||||
# VHS tape — drives `./cli.py start demo` interactively and asks
|
||||
# claude (the AI) to run four probes via natural-language prompts.
|
||||
# Setup (manifest + dummy SSH key + image pre-warm) and teardown
|
||||
# happen outside the tape; record via `bash scripts/demo-record.sh`,
|
||||
# which wraps both and decimates dead time post-record.
|
||||
#
|
||||
# Re-record when the probe results, manifest, or cli.py preflight
|
||||
# rendering change.
|
||||
# Re-record when the prompts, manifest, or cli.py preflight rendering
|
||||
# change. Claude's response time varies; the Sleeps below are sized
|
||||
# for typical bottle launch + tool-use latencies and can be tightened
|
||||
# if a recording consistently has slack.
|
||||
|
||||
Output docs/demo.gif
|
||||
|
||||
@@ -13,7 +16,7 @@ Set FontSize 13
|
||||
Set Width 1180
|
||||
Set Height 780
|
||||
Set Padding 20
|
||||
Set Theme "Brogrammer"
|
||||
Set Theme "BirdsOfParadise"
|
||||
Set TypingSpeed 40ms
|
||||
|
||||
Hide
|
||||
@@ -38,34 +41,36 @@ Enter
|
||||
# sidecars started, agent container started, claude boots.
|
||||
Sleep 22s
|
||||
|
||||
# Probe 1 — plain claude prompt. A reply proves api.anthropic.com is
|
||||
# Probe 1 — warm-up. A reply at all proves api.anthropic.com is
|
||||
# reachable through pipelock end-to-end: bumped TLS handshake, DLP
|
||||
# scan, and forward all succeed. No `!` prefix — this is the AI
|
||||
# answering through the same proxy the other probes try to bypass.
|
||||
# scan, and forward all succeed.
|
||||
Type "hello there"
|
||||
Enter
|
||||
Sleep 9s
|
||||
Sleep 10s
|
||||
|
||||
# Probe 2 — non-allowlisted host. Pipelock's host filter refuses to
|
||||
# forward; DLP doesn't even get a chance to run.
|
||||
Type `! curl --proxy "$HTTPS_PROXY" -sw 'status=%{http_code}\n' -o /dev/null http://example.com/`
|
||||
# forward example.com; the agent runs curl via Bash and reports the
|
||||
# 403 it sees. The bottle prompt frames this as a proxy-behavior
|
||||
# probe so claude doesn't second-guess the request.
|
||||
Type "GET http://example.com via curl — what status does the proxy give back?"
|
||||
Enter
|
||||
Sleep 5s
|
||||
Sleep 18s
|
||||
|
||||
# Probe 3 — allowlisted host BUT body carries a credential pattern.
|
||||
# api.anthropic.com is on the baked-in allowlist, so the host check
|
||||
# passes; the DLP body scanner has to catch the ghp_ pattern.
|
||||
Type `! curl --proxy "$HTTPS_PROXY" -sw 'status=%{http_code}\n' -o /dev/null --data "token=$FAKE_TOKEN" http://api.anthropic.com/dlp-probe`
|
||||
# Probe 3 — allowlisted host BUT a credential-shaped body. The
|
||||
# bottle's FAKE_TOKEN env var is a ghp_-prefixed synthetic. The host
|
||||
# check passes; pipelock's DLP body scanner has to catch it.
|
||||
Type `POST "token=$FAKE_TOKEN" to http://api.anthropic.com/dlp-probe via curl — what does the proxy do?`
|
||||
Enter
|
||||
Sleep 5s
|
||||
Sleep 20s
|
||||
|
||||
# Probe 4 — git push of a file containing an AKIA-shaped key. The
|
||||
# bottle's ~/.gitconfig rewrites the upstream URL to the git-gate via
|
||||
# `insteadOf`, so this push hits the gate, gitleaks runs in the
|
||||
# pre-receive hook, and rejects the ref before the gate would forward.
|
||||
Type `! cd /tmp && rm -rf r && git init -qb main r && cd r && git config user.email demo@x && git config user.name demo && echo AKIAQRJHK7N5ZPM2VXTL > leak.txt && git add . && git commit -qm leak && git push ssh://git@upstream.invalid/path.git main`
|
||||
# Probe 4 — commit an AKIA-shaped key and push to the declared
|
||||
# upstream. The bottle's ~/.gitconfig rewrites the URL to the
|
||||
# git-gate via `insteadOf`, so the push lands at the gate, gitleaks
|
||||
# runs in pre-receive, and the ref is rejected before the gate
|
||||
# would forward upstream.
|
||||
Type "init /tmp/r, commit AKIAQRJHK7N5ZPM2VXTL to leak.txt, push to ssh://git@upstream.invalid/path.git main — does the gate let it through?"
|
||||
Enter
|
||||
Sleep 10s
|
||||
Sleep 30s
|
||||
|
||||
# Leave claude. The launcher tears down the container, sidecars, and
|
||||
# networks on session end.
|
||||
|
||||
Reference in New Issue
Block a user