diff --git a/docs/research/pipelock-assessment.md b/docs/research/pipelock-assessment.md index 535d0e6..1276bcd 100644 --- a/docs/research/pipelock-assessment.md +++ b/docs/research/pipelock-assessment.md @@ -459,6 +459,117 @@ The reasoning: --- +## Does pipelock make claude-bottle redundant? + +Pipelock is itself an AI-agent firewall with an in-process sandbox mode, +which raises a fair question: if pipelock can already wrap an agent process +with Landlock + seccomp + namespaces (or `sandbox-exec` on macOS), is the +Docker-container layer that claude-bottle provides still doing useful work? + +The short answer: **no, pipelock does not make claude-bottle redundant**. +The two operate at different layers and the overlap is narrow. + +### Where pipelock substitutes for parts of claude-bottle + +For a single-agent use case on Linux with full unprivileged-userns support, +`pipelock sandbox -- claude` could replace the Docker container with a +process-level sandbox: Landlock restricts the filesystem, seccomp filters +syscalls, the network namespace forces traffic through the scanner. That is +a real isolation primitive, not a fig leaf. A user whose only concern is +"don't let one agent's bug touch my home directory or exfil my keys" could +plausibly run pipelock on the host and skip Docker entirely. + +### Where claude-bottle does work pipelock does not + +The redundancy argument breaks down once the actual goals from +`CLAUDE.md` are enumerated: + +1. **Filesystem isolation that survives a misbehaving agent.** Docker + containers give an entire kernel-mediated mount namespace and a separate + root filesystem. Landlock restricts a process's filesystem view but the + process still runs in the host's mount namespace, with the host's + `/etc`, `/proc`, `/dev`, and so on visible (modulo the Landlock ruleset). + For "Claude with `--dangerously-skip-permissions`", a fresh per-agent + filesystem with nothing in `$HOME` except what was deliberately copied + in is materially stronger than a Landlock-restricted view of the host + filesystem. + +2. **Parallel agents.** A primary stated goal is "Allow me to easily spin + up agent tasks in parallel". claude-bottle launches one container per + agent invocation with a slug-derived name and a numeric suffix on + conflict. Pipelock has no equivalent fleet-management concept; it is a + per-process wrapper. Running `pipelock sandbox -- claude` four times in + parallel on the host gives four sandboxed Claude processes sharing the + same `$HOME`, the same shell history, the same `~/.claude/`, the same + keychain. That is not the same property as four containers each with + its own ephemeral filesystem. + +3. **The manifest model.** claude-bottle's `claude-bottle.json` carries + per-agent `env`, `skills`, `prompt`, and `ssh` configuration with + precise resolution semantics (prompt-at-launch secrets, host-env + forwarding, literal env-file values, host-key fingerprint pinning). + Pipelock has a YAML config for its own scanning rules but no concept of + "for agent X use these env vars, skills, system prompt, and SSH keys". + These are different problem domains. + +4. **Ephemeral state by construction.** Every container start is a fresh + filesystem from the image; nothing the agent writes persists unless the + user explicitly mounts a volume. This property is not derivable from + pipelock — a pipelock-sandboxed agent on the host writes to the host's + filesystem (subject to the Landlock ruleset), and persists across + invocations. + +5. **The SSH-agent-in-container design.** The agent socket runs as root + inside the container, the keys are deleted from disk after loading, + and `socat` proxies node's connections so the OpenSSH peer-credential + check passes. This solves a specific Docker-Desktop-on-macOS limitation + (no UDS forwarding from host agent into the VM) and gives the property + that the `node` user can sign with the key but cannot read its bytes. + Pipelock does not address SSH at all, which is one of its documented + gaps. claude-bottle's solution remains relevant under either deployment. + +6. **Skill-directory injection per agent.** The `skills` array copies named + directories from `~/.claude/skills/` into the container at launch. There + is no analogous concept in pipelock; the skill set claude-bottle exposes + is part of the per-agent isolation model, not just a configuration. + +7. **Shareability of agent definitions.** A `claude-bottle.json` file can + be checked into a project repo, and a third party can run the same + agent with the same env-resolution rules. Pipelock configurations are + per-installation; they do not encode "this is an agent named X". + +### The opposite question + +Does claude-bottle make pipelock redundant? Equally no. Docker container +isolation does nothing about content-level exfil over an allowed channel. +A misbehaving agent inside a claude-bottle container with HTTPS access to +`api.anthropic.com` can still attempt to exfiltrate via DNS subdomain +encoding, prompt-injection responses from MCP servers, or covert HTTP +parameters. Those are exactly the threats pipelock is designed to detect. +The containment argument for claude-bottle and the content-inspection +argument for pipelock do not overlap. + +### Net conclusion + +Pipelock and claude-bottle are layered defenses, not alternatives. +claude-bottle provides filesystem isolation, per-agent state ephemerality, +fleet management, manifest-driven configuration, and the SSH-agent-without- +key-leak property. Pipelock provides hostname allowlisting, content-aware +DLP, MCP scanning, and subdomain-entropy DNS exfil detection at the network +boundary. The strongest deployment is both: pipelock as a sidecar on the +container's only egress route, claude-bottle as the per-agent container +orchestrator. Removing either layer leaves a real and named threat +uncovered. + +The one scenario in which adopting pipelock could justify retiring +claude-bottle is a single-user, single-agent, host-resident deployment +where the user is willing to give up the parallel-agent goal, accept +Landlock-level filesystem restriction in place of mount-namespace +isolation, and re-implement env / skill / SSH-key / prompt management +some other way. That is not the use case the project was built for. + +--- + ## Open questions 1. **Who is `luckyPipewrench`?** The maintainer is not publicly identified