PRD 0009: Remove ssh-gate and bottle.ssh #13

Merged
didericis merged 5 commits from deprecate-ssh-gate into main 2026-05-13 00:01:01 -04:00
4 changed files with 17 additions and 24 deletions
Showing only changes of commit 30d92bef48 - Show all commits
+7 -19
View File
@@ -78,13 +78,7 @@ that enforces the manifest before it leaves the host.
│ │ built locally) │ │ (TLS bump, DLP,│ │ hosts
│ │ │ │ allowlist) │ │
│ │ skills, env, │ └────────────────┘ │
│ │ ~/.ssh/config, │ │
│ │ ~/.gitconfig │ ssh ┌────────────────┐ │ TCP to
│ │ │ ───────────────► │ socat/ssh image│──┼──► bottle.ssh
│ │ │ │ (alpine/socat, │ │ upstreams
│ │ │ │ L4 forwarder) │ │
│ │ │ └────────────────┘ │
│ │ │ │
│ │ ~/.gitconfig │ │
│ │ │ git ops ┌────────────────┐ │ SSH (push/
│ │ │ ───────────────► │ git-gate image │──┼──► fetch) to
│ │ │ │ (gitleaks + │ │ bottle.git
@@ -98,16 +92,12 @@ that enforces the manifest before it leaves the host.
- **agent image** — built from the repo `Dockerfile` (`node:22-slim`
base) on first run; runs `claude` with the manifest-granted skills,
env vars, `~/.ssh/config`, and `~/.gitconfig` (the latter for the
git-gate's `pushInsteadOf` rules when `bottle.git` is set).
env vars, and `~/.gitconfig` (the latter for the git-gate's
`insteadOf` rules when `bottle.git` is set).
- **pipelock image** — per-agent sidecar. Terminates the agent's
outbound HTTP/HTTPS, enforces the resolved allowlist, runs DLP
scanning. Design in `docs/prds/0001-per-agent-egress-proxy-via-pipelock.md`
and `docs/prds/0006-pipelock-tls-interception.md`.
- **socat/ssh image** — per-agent sidecar built on `alpine/socat`.
One container, one socat listener per `bottle.ssh` entry, each
forwarding TCP to the upstream `Hostname:Port`. SSH does *not* go
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` over `git://` as a bidirectional mirror of each
@@ -160,14 +150,12 @@ project entries overriding home entries on key conflict).
"GIT_AUTHOR_NAME": "didericis"
},
"ssh": [
"git": [
{
"Host": "gitea",
"Hostname": "gitea.dideric.is",
"User": "git",
"Port": 30009,
"Name": "claude-bottle",
"Upstream": "ssh://git@gitea.dideric.is:30009/didericis/claude-bottle.git",
"IdentityFile": "/Users/didericis/.ssh/id_ed25519_gitea",
"KnownHostKey": "gitea.dideric.is ssh-ed25519 AAAA..."
"KnownHostKey": "ssh-ed25519 AAAA..."
}
],
-1
View File
@@ -2,7 +2,6 @@
"bottles": {
"default": {
"env": {},
"ssh": [],
"egress": {
"allowlist": [
"github.com",
+2 -3
View File
@@ -93,9 +93,8 @@ class GitGatePlan:
def git_gate_upstreams_for_bottle(bottle: Bottle) -> tuple[GitGateUpstream, ...]:
"""Lift each `bottle.git` entry into a GitGateUpstream. Cross-entry
validation (unique Names, no shadow route with bottle.ssh) already
ran in `manifest.Bottle.from_dict`."""
"""Lift each `bottle.git` entry into a GitGateUpstream. Unique-Name
validation already ran in `manifest.Bottle.from_dict`."""
return tuple(
GitGateUpstream(
name=e.Name,
+8 -1
View File
@@ -1,9 +1,16 @@
# PRD 0007: SSH egress gate
- **Status:** Draft
- **Status:** Superseded by PRD 0009 (2026-05-13)
- **Author:** didericis
- **Created:** 2026-05-12
> **Superseded.** The ssh-gate sidecar and `bottle.ssh` manifest field
> described below were removed in PRD 0009. Every upstream this PRD
> targeted has since been folded into PRD 0008's git-gate, which
> covers the same use case with credential isolation and gitleaks
> scanning instead of bare L4 forwarding. Kept in-tree for the
> history of intent.
## Summary
Per-agent TCP-forwarder sidecar built from `bottle.ssh` entries; SSH stops