docs: redraw README architecture to show pipelock as HTTP/S chokepoint
The previous diagram showed three parallel egress lanes — agent ↔ pipelock, agent ↔ git-gate, agent ↔ cred-proxy — each going off-box independently. That was true of an earlier shape but is now wrong on two counts: 1. cred-proxy's outbound HTTPS routes through pipelock (set when the SSRF / CA-trust wiring landed). All cred-proxy upstream bytes pass pipelock's allowlist + body scanner. 2. git-gate's SSH push/fetch is direct out the egress network and has never gone through pipelock — pipelock is HTTP-only. Reflect both: the diagram now collapses to one HTTP/HTTPS chokepoint (pipelock) that the agent and cred-proxy share, plus a separate SSH lane for git-gate. Prose paragraph above the diagram updated to call out the "everything except SSH" framing explicitly. Verified against the current code: HTTPS_PROXY=pipelock set on the agent in launch.py and on cred-proxy in DockerCredProxy.start; git-gate's create-args carry no proxy env vars.
This commit is contained in:
@@ -71,43 +71,53 @@ pieces of v1.
|
||||
|
||||
A bottle is the agent container plus up to three per-protocol egress
|
||||
sidecars on a per-agent Docker `--internal` network. The agent has no
|
||||
default route off-box; its only way out is through the pipelock
|
||||
sidecar (for HTTP/HTTPS), the git-gate sidecar (for git operations
|
||||
against declared upstreams), or the cred-proxy sidecar (for API
|
||||
calls that need a manifest-declared token — Anthropic OAuth, GitHub
|
||||
PAT, Gitea PAT, npm). Each sidecar also sits on an egress network
|
||||
that does have internet access, so the agent's traffic always passes
|
||||
through a container that enforces the manifest before it leaves the
|
||||
host.
|
||||
default route off-box. All HTTP and HTTPS egress — from the agent
|
||||
*and* from cred-proxy when it dials an upstream — funnels through
|
||||
pipelock, where the egress allowlist, TLS interception, and
|
||||
request-body DLP scanner enforce the manifest before any byte leaves
|
||||
the host. The only egress that doesn't traverse pipelock is git-gate's
|
||||
SSH push/fetch to `bottle.git` upstreams — pipelock can't proxy SSH,
|
||||
so git-gate is its own L4-style egress path with gitleaks doing the
|
||||
pre-receive scan.
|
||||
|
||||
```
|
||||
host ( ./cli.py )
|
||||
│
|
||||
starts │ stops
|
||||
▼
|
||||
┌─────────────────────────── bottle ──────────────────────────┐
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ agent image │ HTTPS_PROXY ┌────────────────┐ │ HTTPS to
|
||||
│ │ (claude-code, │ ───────────────► │ pipelock image │──┼──► allowlisted
|
||||
│ │ built locally) │ │ (TLS bump, DLP,│ │ hosts
|
||||
│ │ │ │ allowlist) │ │
|
||||
│ │ skills, env, │ └────────────────┘ │
|
||||
│ │ ~/.gitconfig, │ │
|
||||
│ │ ~/.npmrc, tea │ git ops ┌────────────────┐ │ SSH (push/
|
||||
│ │ │ ───────────────► │ git-gate image │──┼──► fetch) to
|
||||
│ │ │ │ (gitleaks + │ │ bottle.git
|
||||
│ │ environ: URLs │ │ git daemon) │ │ upstreams
|
||||
│ │ only, no real │ └────────────────┘ │
|
||||
│ │ tokens │ bearer-auth ┌────────────────┐ │ HTTPS to
|
||||
│ │ │ ───────────────► │ cred-proxy │──┼──► bottle.tokens
|
||||
│ │ │ HTTP, plain │ (strips/injects│ │ upstreams
|
||||
│ │ │ │ Authorization)│ │ (with the
|
||||
│ └──────────────────┘ └────────────────┘ │ real token)
|
||||
│ │
|
||||
│ agent on internal network (no default route); │
|
||||
│ sidecars also attached to an egress network. │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
┌─────────────────────────── bottle ──────────────────────────────────┐
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ agent image │ HTTPS_PROXY │
|
||||
│ │ (claude-code, │ ────────────────────────┐ │
|
||||
│ │ built locally) │ │ │
|
||||
│ │ │ plain HTTP │ │
|
||||
│ │ skills, env, │ (token injection) ┌────▼─────────┐ │
|
||||
│ │ ~/.gitconfig, │ ──────────────────►│ cred-proxy │ │
|
||||
│ │ ~/.npmrc, tea │ │ (strips/inj │ │
|
||||
│ │ │ │ Authoriz.) │ │
|
||||
│ │ environ: URLs │ └─────┬────────┘ │
|
||||
│ │ only, no real │ HTTPS_PROXY │ │
|
||||
│ │ tokens │ ▼ │
|
||||
│ │ │ ┌────────────────┐ │ HTTPS to
|
||||
│ │ │ │ pipelock image │──────────┼──► allowlisted
|
||||
│ │ │ │ (TLS bump, DLP │ │ hosts (incl.
|
||||
│ │ │ │ body scan, │ │ cred-proxy
|
||||
│ │ │ │ allowlist) │ │ upstreams)
|
||||
│ │ │ └────────────────┘ │
|
||||
│ │ │ │
|
||||
│ │ │ git:// ┌────────────────┐ │ SSH push/fetch
|
||||
│ │ │ ────────────────►│ git-gate image │──────────┼──► to bottle.git
|
||||
│ │ │ │ (gitleaks + │ │ upstreams
|
||||
│ └──────────────────┘ │ git daemon) │ │ (direct — not
|
||||
│ └────────────────┘ │ via pipelock)
|
||||
│ │
|
||||
│ agent on internal network (no default route); pipelock, │
|
||||
│ cred-proxy, and git-gate straddle internal + egress networks. │
|
||||
│ pipelock is the single HTTP/HTTPS chokepoint — cred-proxy's │
|
||||
│ outbound traverses it too. git-gate's SSH egress is direct │
|
||||
│ because pipelock is HTTP-only. │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
- **agent image** — built from the repo `Dockerfile` (`node:22-slim`
|
||||
|
||||
Reference in New Issue
Block a user