PRD 0008: Git gate #11
@@ -56,12 +56,14 @@ pieces of v1.
|
|||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
A bottle is three containers on a per-agent Docker `--internal`
|
A bottle is the agent container plus up to three per-protocol egress
|
||||||
network. The agent has no default route off-box; its only way out is
|
sidecars on a per-agent Docker `--internal` network. The agent has no
|
||||||
through the pipelock sidecar (for HTTP/HTTPS) or the ssh-gate sidecar
|
default route off-box; its only way out is through the pipelock
|
||||||
(for SSH). Both sidecars also sit on an egress network that does have
|
sidecar (for HTTP/HTTPS), the ssh-gate sidecar (for SSH), or the
|
||||||
internet access, so the agent's traffic always passes through a
|
git-gate sidecar (for `git push`). Each sidecar also sits on an
|
||||||
container that enforces the manifest before it leaves the host.
|
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.
|
||||||
|
|
||||||
```
|
```
|
||||||
host ( ./cli.py )
|
host ( ./cli.py )
|
||||||
@@ -76,11 +78,17 @@ container that enforces the manifest before it leaves the host.
|
|||||||
│ │ built locally) │ │ (TLS bump, DLP,│ │ hosts
|
│ │ built locally) │ │ (TLS bump, DLP,│ │ hosts
|
||||||
│ │ │ │ allowlist) │ │
|
│ │ │ │ allowlist) │ │
|
||||||
│ │ skills, env, │ └────────────────┘ │
|
│ │ skills, env, │ └────────────────┘ │
|
||||||
│ │ ~/.ssh/config │ │
|
│ │ ~/.ssh/config, │ │
|
||||||
│ │ │ ssh ┌────────────────┐ │ TCP to
|
│ │ ~/.gitconfig │ ssh ┌────────────────┐ │ TCP to
|
||||||
│ │ │ ───────────────► │ socat/ssh image│──┼──► bottle.ssh
|
│ │ │ ───────────────► │ socat/ssh image│──┼──► bottle.ssh
|
||||||
│ │ │ │ (alpine/socat, │ │ upstreams
|
│ │ │ │ (alpine/socat, │ │ upstreams
|
||||||
│ │ │ │ L4 forwarder) │ │
|
│ │ │ │ L4 forwarder) │ │
|
||||||
|
│ │ │ └────────────────┘ │
|
||||||
|
│ │ │ │
|
||||||
|
│ │ │ git push ┌────────────────┐ │ SSH (push)
|
||||||
|
│ │ │ ───────────────► │ git-gate image │──┼──► to bottle.git
|
||||||
|
│ │ │ │ (gitleaks + │ │ upstreams
|
||||||
|
│ │ │ │ git daemon) │ │
|
||||||
│ └──────────────────┘ └────────────────┘ │
|
│ └──────────────────┘ └────────────────┘ │
|
||||||
│ │
|
│ │
|
||||||
│ agent on internal network (no default route); │
|
│ agent on internal network (no default route); │
|
||||||
@@ -90,7 +98,8 @@ container that enforces the manifest before it leaves the host.
|
|||||||
|
|
||||||
- **agent image** — built from the repo `Dockerfile` (`node:22-slim`
|
- **agent image** — built from the repo `Dockerfile` (`node:22-slim`
|
||||||
base) on first run; runs `claude` with the manifest-granted skills,
|
base) on first run; runs `claude` with the manifest-granted skills,
|
||||||
env vars, and `~/.ssh/config`.
|
env vars, `~/.ssh/config`, and `~/.gitconfig` (the latter for the
|
||||||
|
git-gate's `pushInsteadOf` rules when `bottle.git` is set).
|
||||||
- **pipelock image** — per-agent sidecar. Terminates the agent's
|
- **pipelock image** — per-agent sidecar. Terminates the agent's
|
||||||
outbound HTTP/HTTPS, enforces the resolved allowlist, runs DLP
|
outbound HTTP/HTTPS, enforces the resolved allowlist, runs DLP
|
||||||
scanning. Design in `docs/prds/0001-per-agent-egress-proxy-via-pipelock.md`
|
scanning. Design in `docs/prds/0001-per-agent-egress-proxy-via-pipelock.md`
|
||||||
@@ -99,9 +108,17 @@ container that enforces the manifest before it leaves the host.
|
|||||||
One container, one socat listener per `bottle.ssh` entry, each
|
One container, one socat listener per `bottle.ssh` entry, each
|
||||||
forwarding TCP to the upstream `Hostname:Port`. SSH does *not* go
|
forwarding TCP to the upstream `Hostname:Port`. SSH does *not* go
|
||||||
through pipelock. Design in `docs/prds/0007-ssh-egress-gate.md`.
|
through pipelock. Design in `docs/prds/0007-ssh-egress-gate.md`.
|
||||||
|
- **git-gate image** — per-agent sidecar built on `zricethezav/gitleaks`
|
||||||
|
(alpine + gitleaks + git-daemon + openssh-client). Runs
|
||||||
|
`git daemon --enable=receive-pack` so the agent can push to it
|
||||||
|
via `git://`; a pre-receive hook gitleaks-scans each incoming ref
|
||||||
|
and forwards clean refs to the real upstream over SSH using a
|
||||||
|
credential the agent never sees. Brought up only when `bottle.git`
|
||||||
|
has entries. Design in `docs/prds/0008-git-gate.md`.
|
||||||
|
|
||||||
When the agent exits, `cli.py` tears down both sidecars and the two
|
When the agent exits, `cli.py` tears down every sidecar that was
|
||||||
networks; nothing about a bottle persists between runs.
|
brought up and the two networks; nothing about a bottle persists
|
||||||
|
between runs.
|
||||||
|
|
||||||
## Quickstart
|
## Quickstart
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user