diff --git a/docs/research/pipelock-assessment.md b/docs/research/pipelock-assessment.md new file mode 100644 index 0000000..535d0e6 --- /dev/null +++ b/docs/research/pipelock-assessment.md @@ -0,0 +1,531 @@ +# Pipelock assessment for claude-bottle egress control + +Research into whether pipelock — an open-source AI agent firewall — +is a suitable replacement for, or complement to, the egress-control +approaches documented in `network-egress-guard.md` and the content- +tripwire approach sketched in `secret-exfil-tripwire-encodings.md`. + +## Summary + +- Pipelock (`luckyPipewrench/pipelock`) is an open-source AI agent + firewall implemented as a single Go binary. It sits inline as an HTTP + forward proxy and, optionally, applies OS-level process containment. It + is the most directly relevant tool found for claude-bottle's egress / + data-exfiltration concerns. +- Its strongest differentiator over the v1 iptables recommendation is + **content-aware DLP**: it matches 48 credential patterns across + multiple encodings in outbound request bodies and URL subdomains, + covering ground that iptables and smokescreen cannot touch. +- The process-containment sandbox (Landlock + seccomp + network + namespaces) is **Linux-only at the kernel level**. In-container on + macOS Docker Desktop the sandbox degrades to `--best-effort` mode, + which relies on `HTTPS_PROXY` env var interception and is bypassable + via raw socket calls or env-var unsetting. The proxy scanning layer + works on both platforms. +- Adopting pipelock as a **sidecar proxy** (replacing the smokescreen v2 + recommendation) is well-supported and adds DLP and subdomain-entropy + DNS exfil detection that smokescreen lacks. The sidecar topology avoids + the `--best-effort` degradation problem entirely. +- Recommendation: skip pipelock as an in-container self-contained guard + (the `--best-effort` caveat is significant on macOS Docker Desktop); + adopt it as the **sidecar proxy** in place of smokescreen, pairing it + with the in-container iptables+dnsmasq layer from the v1 plan. + +--- + +## Identification + +- **Canonical URL**: +- **Project site / documentation**: +- **Maintainer**: `luckyPipewrench` (GitHub org); also associated with + the `pipelab.org` domain. No named individual maintainer is surfaced in + search results; the project presents as a company or team product. +- **License**: dual-licensed. Core under **Apache 2.0**; an `enterprise/` + subtree under **Elastic License v2 (ELv2)**, per the badges and `LICENSE` + layout in the project README + ([README](https://github.com/luckyPipewrench/pipelock/blob/main/README.md)). + Which capabilities sit on which side of that line is a question this note + does not answer; before adoption, the `enterprise/` directory should be + inspected to confirm that the features cited below (DLP patterns, + subdomain entropy, MCP scanning, request redaction, sidecar topology) are + available under the Apache 2.0 core. Mediator-signed action receipts and + some attestation features may be ELv2-gated. +- **Current stable release**: v2.3.0, published **2026-04-25** per the + GitHub release metadata + ([release v2.3.0](https://github.com/luckyPipewrench/pipelock/releases/tag/v2.3.0)). + An accompanying Help Net Security announcement appeared 2026-05-04 + ([helpnetsecurity.com](https://www.helpnetsecurity.com/2026/05/04/pipelock-open-source-ai-agent-firewall/)); + earlier rough drafts of this note conflated the announcement date with + the release date. +- **Project age**: repository created **2026-02-08** per the GitHub API, + so ~3 months old at the time of this note. v2.1.1, v2.1.2, v2.2.0, v2.3.0 + tags exist, indicating active iteration. +- **Language / distribution**: Go; ships as a single static binary (~12–20 MB, + sources differ slightly). Available via Docker image + (`ghcr.io/luckypipewrench/pipelock:latest`), Homebrew + (`brew install luckyPipewrench/tap/pipelock`), and + `go install`. Stated zero runtime dependencies. + +**What it actually does.** Pipelock is an application-layer HTTP forward +proxy designed specifically for AI agent deployments. It sits between the +agent process and the network and applies an 11-layer scanning pipeline to +all outbound HTTP, HTTPS (via CONNECT), WebSocket, and MCP traffic. The +pipeline covers: scheme enforcement, CRLF injection detection, path traversal +blocking, domain blocklisting, DLP credential matching, subdomain entropy +analysis, SSRF protection (RFC 1918 + metadata endpoints blocked by default), +rate limiting, URL length limits, and per-domain data budgets. An optional +sandbox mode on Linux wraps the agent child process with Landlock filesystem +restrictions, seccomp syscall filtering, and a network namespace that forces +all traffic through pipelock's scanner. On macOS the equivalent is +`sandbox-exec` with dynamic SBPL profiles. The tool is positioned at the +intersection of egress control and AI-specific threat vectors (prompt +injection, MCP tool poisoning, credential leaks in LLM outputs). + +**Disambiguation note.** The name "pipelock" could in principle refer to +Python pip lockfile tooling or other unrelated utilities. In the context of +containerized AI agent egress filtering there is exactly one relevant project: +`luckyPipewrench/pipelock`. No other tool bearing that name addresses the +egress / DLP problem space. + +--- + +## Capabilities vs the threat model + +### HTTP(S) egress + +Pipelock covers HTTP and HTTPS (CONNECT) egress in full. Its forward proxy +mode requires zero code changes in the agent — Claude Code already respects +`HTTP_PROXY` / `HTTPS_PROXY` environment variables, which is the standard +injection vector +([Claude Code network config docs](https://code.claude.com/docs/en/network-config)). +In `strict` mode, all outbound HTTP is blocked unless the destination is on +the `api_allowlist`; in `balanced` and `audit` modes the allowlist is advisory. +This covers threat 1 (HTTP(S) data exfiltration) from the `network-egress-guard.md` +threat model. + +The proxy scanning pipeline also covers outbound WebSocket and MCP traffic, +which the iptables approach allows through on the basis of IP address alone +and which smokescreen passes without content inspection. Pipelock's +bidirectional MCP scanner catches credential leaks in MCP tool call arguments +and prompt-injection payloads in tool responses, neither of which an IP- or +CONNECT-hostname-based firewall can detect. + +What it leaves uncovered at this layer: raw TCP (non-HTTP), UDP, and ICMP. +These are the same gaps documented for smokescreen in `network-egress-guard.md` +and must be closed by a complementary iptables or `--network none` layer. + +### DNS exfiltration + +This is pipelock's most significant advantage over the v1 iptables +recommendation and over smokescreen. The `network-egress-guard.md` note +flags DNS tunneling (threat 2) as a real gap in IP-based allowlists and +notes that the only partial mitigations are a controlled resolver (dnsmasq) +plus blocking direct UDP/53 access to non-allowlisted resolvers. + +Pipelock addresses the same problem from a different angle: it runs a +**subdomain entropy analysis** pass against every URL before resolving it. +This catches base64- and hex-encoded keys embedded in subdomain labels — +the dominant DNS exfiltration technique — by detecting abnormally high +Shannon entropy in the leftmost subdomain components. Crucially, the DLP +scanner runs **before** DNS resolution, meaning a secret encoded into a +subdomain cannot escape via the DNS query itself even if the HTTP request +is later blocked +([pipelab.org/pipelock/](https://pipelab.org/pipelock/)). +A DEV Community post by the maintainer explicitly addresses the +"AI agents leak API keys through DNS queries" scenario +([dev.to/luckypipewrench/your-ai-agent-leaks-api-keys-through-dns-queries-5c1d](https://dev.to/luckypipewrench/your-ai-agent-leaks-api-keys-through-dns-queries-5c1d)). + +Coverage gaps remain. Pipelock operates at the HTTP proxy layer; it does +not intercept raw UDP port 53 traffic from the container. An agent making a +direct DNS query (not mediated through pipelock's resolver) can still +exfiltrate via DNS. Closing this gap still requires one of: +- Blocking direct UDP/53 from the container via iptables and routing all + DNS through a controlled resolver, or +- Combining pipelock's subdomain-entropy check (effective at the URL layer) + with an in-container dnsmasq that blocks non-allowlisted queries. + +The dnsmasq complement from the v1 plan therefore remains relevant even if +pipelock is adopted as the sidecar proxy. + +### RFC 1918 / lateral movement + +Pipelock blocks connections to private IP ranges, cloud metadata endpoints +(169.254.169.254), and link-local addresses as part of its SSRF protection +layer, which is active by default +([pipelock/docs/configuration.md](https://github.com/luckyPipewrench/pipelock/blob/main/docs/configuration.md)). +This matches the behavior of smokescreen, which also blocks RFC 1918 by +default and was cited in `network-egress-guard.md` as a primary advantage +of the proxy sidecar approach over raw iptables rules. + +Pipelock adds DNS rebinding protection on top, which smokescreen does not +document: it checks that the IP a hostname resolves to at connection time +is not in a private range, guarding against the class of attack where a +benign domain is resolved to a public IP during the allowlist check and then +re-resolved to a private IP when the connection is made. + +Domains can be whitelisted from the SSRF IP check individually (for +legitimate VPN-routed internal APIs), while the DLP scanner continues to +apply to those connections +([pipelab.org/pipelock/](https://pipelab.org/pipelock/)). + +### Content-based exfil detection (DLP) + +This is the area where pipelock most directly covers ground not addressed +by either the v1 iptables approach or the smokescreen sidecar, and it maps +directly to the problem space of `secret-exfil-tripwire-encodings.md`. + +The DLP layer matches **48 credential patterns** across the URL, headers, and +request body. It uses four checksum validators (Luhn, mod-97, ABA routing +numbers, WIF bitcoin keys) to reduce false positives and applies +encoding-aware decoding before matching: at minimum base64, hex, multi-layer +URL encoding, and Unicode evasion (confusable characters, combining marks, +control character insertion, field splitting, whitespace manipulation) +([pipelab.org/pipelock/](https://pipelab.org/pipelock/), +[github.com/luckyPipewrench/pipelock/blob/main/docs/security-assurance.md](https://github.com/luckyPipewrench/pipelock/blob/main/docs/security-assurance.md)). +The subdomain entropy check covers environment variable leaks (values 16+ +characters with Shannon entropy above 3.0) in base64, hex, and base32 forms. + +As of v2.3.0, the DLP layer also covers **request redaction**: matched +secrets are rewritten in-flight with typed placeholders +(``, etc.) rather than simply blocked, preserving the +class information for downstream tooling while stripping the value from the +outbound request +([pipelab.org/blog/pipelock-v230-release/](https://pipelab.org/blog/pipelock-v230-release/)). +This addresses the use case described in `secret-exfil-tripwire-encodings.md` +where the goal is detection rather than total blocking. + +Coverage relative to the encoding catalog in `secret-exfil-tripwire-encodings.md`: +the 25-encoding table in that note ranges from base64 (covered) through +ROT13, double base64, and gzip+base64. Pipelock's documented encoding +coverage (base64, hex, URL encoding, Unicode normalization) covers +approximately the first ten entries of that catalog. There is no documented +coverage for ROT13, ROT47, gzip+base64, or steganographic encodings — consistent +with that note's conclusion that those are diminishing-returns cases for a +non-adversarially-sophisticated agent. + +The encoding-normalization pipeline applies before the pattern match, so +a secret base64-encoded inside a JSON body will be decoded and matched; it +is not necessary to pre-compute all encoded forms and load them as separate +patterns, which was the DIY approach sketched in `secret-exfil-tripwire-encodings.md`. + +### Scope gaps + +The following threat-model items from `network-egress-guard.md` are +**not** addressed by pipelock at the proxy layer: + +- **Raw TCP (non-HTTP)**: direct database connections, LDAP, custom + protocols, and anything that does not go through `HTTPS_PROXY`. These + require a complementary IP-based default-deny layer (iptables or + `--network none`). +- **UDP**: DNS queries bypassing the proxy, QUIC, ICMP covert channels. + Pipelock's subdomain entropy check fires on URLs it sees; it does not + intercept raw UDP 53 packets. +- **Domain fronting**: an agent can send `CONNECT allowed-host.com:443` + through the proxy but embed a different SNI inside the TLS session. + Pipelock does not perform TLS inspection (no CA trust injection) and + cannot verify SNI vs. CONNECT header. The same limitation is shared + with smokescreen and is documented in `network-egress-guard.md` as a + known gap for the non-TLS-terminating proxy approach. +- **SSH egress content**: SSH sessions to permitted hosts are opaque. + Same limitation noted in both prior research notes. +- **Agent killing the proxy process**: if pipelock runs inside the same + container as the agent rather than as a sidecar, the agent's shell + access could kill the proxy process. The sidecar topology mitigates this. + +--- + +## Fit for claude-bottle + +### Deployment topology + +Pipelock explicitly supports two deployment shapes relevant to +claude-bottle: + +**Sidecar proxy.** A separate container running pipelock on an +`--internal` Docker network, with the agent container's only route to the +outside world through the proxy. Pipelock can generate a ready-made Docker +Compose file for this topology: + +``` +pipelock generate docker-compose --agent claude-code -o docker-compose.yaml +``` + +The agent container is placed on a network with `internal: true` (which +removes the default gateway at the iptables level inside Docker's network +plumbing); the only reachable address is the pipelock container. The agent +sets `HTTPS_PROXY` / `HTTP_PROXY` to the pipelock service address. This is +structurally identical to the smokescreen sidecar described in +`network-egress-guard.md`, but with the richer scanning pipeline. The +Docker image is available at `ghcr.io/luckypipewrench/pipelock:latest` +([pipelock/docs/guides/deployment-recipes.md](https://github.com/luckyPipewrench/pipelock/blob/main/docs/guides/deployment-recipes.md)). + +**In-container with sandbox enabled.** Pipelock forks the agent as a child +process, wraps it with OS-level containment, and routes all traffic through +its own scanner. This avoids a second container but introduces the +`--best-effort` degradation problem described below and means the agent and +the proxy run in the same failure domain. + +The sidecar topology is recommended for claude-bottle because it matches +the existing bash-orchestrated multi-container model (the SSH key agent +already uses a separate process), keeps pipelock outside the agent's kill +reach, and avoids the `--best-effort` issue on macOS Docker Desktop. + +The claude-bottle manifest model would need one new piece of plumbing: a +per-agent pipelock ACL YAML generated from the manifest's `allowlist` +and `ssh` entries, analogous to what the smokescreen section of +`network-egress-guard.md` already sketches. The `cli.sh` changes required +are the same pattern: `docker network create --internal`, `docker run` for +the proxy container, then `docker run` for the agent with `HTTPS_PROXY` +injected. + +### macOS Docker Desktop compatibility + +The proxy layer of pipelock (the HTTP forward proxy, DLP scanning, SSRF +blocking, subdomain entropy analysis) works on both macOS and Linux. The +Docker image and Homebrew package are available for macOS. There are no +Linux-specific kernel dependencies for the proxy functionality itself. + +The **sandbox mode** is where the platform split matters. On Linux the +sandbox uses Landlock LSM, seccomp, and network namespaces, all requiring +Linux 5.13+ kernel features. On macOS it uses `sandbox-exec` with SBPL +profiles, which requires macOS 13+. When pipelock runs **inside** a Docker +container on macOS Docker Desktop, the container's kernel is Linux (LinuxKit), +so the sandbox mode attempts to use the Linux path. Whether the LinuxKit +kernel version in Docker Desktop ships with the necessary Landlock ABI v1 +support (Linux 5.13+) and allows `CLONE_NEWUSER` for unprivileged network +namespaces is a version-dependent question not authoritatively answered in +the pipelock documentation. + +Pipelock itself documents that if `CLONE_NEWUSER` is unavailable inside a +container, it falls back to `--best-effort` mode: + +> When user namespaces are unavailable, pipelock cannot create a network +> namespace for the child process, so outbound traffic enforcement relies +> only on HTTP_PROXY / HTTPS_PROXY environment variables, which can be +> bypassed. +> ([github.com/luckyPipewrench/pipelock](https://github.com/luckyPipewrench/pipelock)) + +In the **sidecar topology** this problem disappears: pipelock runs as its +own container with no child-process sandbox, and enforcement is achieved via +Docker's `--internal` network flag (which removes the default route at the +iptables level in the LinuxKit VM). The agent cannot bypass this by unsetting +`HTTPS_PROXY` because there is literally no route to the internet from its +network namespace. The sidecar is therefore the correct deployment shape for +macOS Docker Desktop. + +### Sandbox mode in-container caveat + +Even on a Linux Docker Engine host, running pipelock in sandbox mode inside +a container requires careful capability configuration. The sandbox uses +`CLONE_NEWUSER` to create an unprivileged network namespace; Docker's default +seccomp profile may block this syscall. The fix is either to adjust the +container's seccomp profile, set `kernel.unprivileged_userns_clone=1` on the +host, or use the sidecar topology instead. In `--best-effort` mode pipelock +emits a startup `WARNING: DEGRADED` log line and relies only on +proxy-environment-variable interception — meaning a subprocess that calls +`unsetenv("HTTPS_PROXY")` before making a socket call bypasses the scanner. + +The pipelock documentation explicitly acknowledges this bypass and recommends +the sidecar topology as the kernel-enforced equivalent for containerized +deployments +([github.com/luckyPipewrench/pipelock](https://github.com/luckyPipewrench/pipelock)). + +### Configuration shape and manifest integration + +Pipelock is configured via a single YAML file. A starter config can be +generated with `pipelock generate config --preset balanced > pipelock.yaml`. +The config watcher picks up changes at runtime (100ms debounce on SIGHUP or +file events), so per-agent ACL updates do not require a container restart. + +For claude-bottle, the relevant per-agent configuration is the domain +allowlist. The manifest already captures the necessary inputs: the `ssh` +array has target hostnames, and an `allowlist` key is planned for the v2 +egress work (per `network-egress-guard.md`). Generating a per-agent pipelock +YAML from those manifest fields is the same pattern as the per-agent +smokescreen ACL YAML described in that note — a straightforward `lib/` script +producing a temp-file YAML and `docker cp`'ing it into the proxy container. + +The YAML format is more expressive than smokescreen's YAML ACL: it also +carries DLP sensitivity settings, per-domain data budgets, and rate limits. +For a first integration pass, only the `api_allowlist` section needs +per-agent population; the rest of the defaults are appropriate for the +claude-bottle threat model. + +### Runtime footprint + +A single Go binary, ~12–20 MB (sources report slightly different figures; the +GitHub description says "~20 MB" and the randomcpu.com writeup says "~12 MB"). +Zero runtime dependencies; the Go standard library is statically linked. This +is consistent with claude-bottle's low-dependency principle. Adding Go as a +host build dependency is not required — the binary is fetched from a Docker +image or Homebrew. + +The Docker image at `ghcr.io/luckypipewrench/pipelock:latest` is the natural +integration point for the sidecar topology. No new runtimes or package managers +are needed on the host; the manifest-and-launch scripts stay in bash. + +One new concept is the pipelock YAML config file format. It is documented and +generated by `pipelock generate config`; the schema is YAML with clear keys. It +is simpler to reason about than iptables rules and does not require per-container +privilege grants. + +--- + +## Comparison table + +The axes match those used in `network-egress-guard.md` with three additions +(DLP/content detection, DNS subdomain entropy, project recency) to capture +pipelock's differentiators. + +| | iptables+dnsmasq (v1) | smokescreen sidecar (v2) | pipelock sidecar | do nothing | +|---|---|---|---|---| +| HTTP(S) egress blocking | hostname-resolved IPs only; CDN over-permissioning risk | hostname (CONNECT) | hostname (CONNECT) + 11-layer scan | none | +| DNS exfil — raw UDP | blocked (dnsmasq + iptables) | not blocked | not blocked (proxy layer only) | not blocked | +| DNS subdomain entropy detection | no | no | yes, pre-resolution | no | +| Blocks RFC 1918 by default | only if explicitly added to rules | yes | yes, + DNS rebinding | no | +| Content-based DLP (credential patterns) | no | no | yes, 48 patterns + encoding normalization | no | +| MCP / WebSocket scanning | no | no | yes, bidirectional | no | +| Domain fronting bypass | possible | possible | possible (no TLS termination) | n/a | +| macOS Docker Desktop (sidecar mode) | yes | yes | yes | yes | +| macOS Docker Desktop (in-container sandbox) | yes | n/a | degraded (--best-effort) | yes | +| NET_ADMIN / NET_RAW required | yes | no | no (sidecar) | no | +| New runtime on host | no | Go image (docker pull) | Go image (docker pull) | no | +| Config format | bash script + iptables rules | YAML ACL | YAML (generated by CLI) | n/a | +| Implementation effort | low–medium (adapt existing script) | medium | medium (similar to smokescreen) | none | +| Project maturity (as of 2026-05-08) | battle-tested (Linux kernel + Anthropic devcontainer) | battle-tested (Stripe production) | v2.3.0 (2026-04-25), repo ~3mo old, Apache 2.0 core + ELv2 enterprise | n/a | + +--- + +## Recommendation + +**Adopt pipelock as the v2 sidecar proxy in place of smokescreen.** + +The reasoning: + +1. **It replaces smokescreen with a strict superset.** Pipelock covers + everything smokescreen covers (CONNECT-based hostname allowlisting, + RFC 1918 blocking, Docker `--internal` network isolation) and adds DLP, + subdomain-entropy DNS exfil detection, MCP scanning, and request + redaction. The integration shape for claude-bottle is identical: a + separate container on an internal Docker network, with the agent's + `HTTPS_PROXY` pointing at it. The `cli.sh` changes are the same pattern. + +2. **The DLP layer is the most direct answer to the content-tripwire gap.** + The `secret-exfil-tripwire-encodings.md` note concluded that no + off-the-shelf tool did exactly what was needed and sketched a ~200-line + Python DIY. Pipelock's 48-pattern, encoding-aware DLP pipeline with + built-in false-positive reduction is a production-ready answer to that + gap, without writing custom code. + +3. **The `--best-effort` problem does not apply to the sidecar topology.** + The concern about Linux namespace availability inside Docker containers + is real, but irrelevant when pipelock runs as a sidecar in its own + container. The network isolation is enforced by Docker's `--internal` + flag at the LinuxKit level, not by pipelock's in-process sandbox. + +4. **The v1 iptables layer should be kept.** Pipelock covers HTTP/HTTPS + only; raw TCP, UDP, and ICMP still need the iptables default-deny. + The existing v1 plan (iptables + dnsmasq for DNS + `NET_ADMIN`) remains + necessary as the IP-level floor. Pipelock sits above it, not instead of it. + The dnsmasq layer also closes the raw-UDP-53 gap that pipelock's proxy + layer cannot reach. + +5. **The project is young.** v2.3.0 shipped on 2026-04-25, the repository + was created 2026-02-08 — roughly three months of public history at the + time of this note. The `luckyPipewrench` org does not appear to be a + well-known security vendor with a published track record. This is a + legitimate reason for caution. Smokescreen has years of production use at + Stripe. Pipelock should be evaluated against its code (Apache 2.0 core, + ELv2 enterprise subtree) before being trusted at the enforcement boundary. + The appropriate response is to keep the iptables layer as the primary + enforcement mechanism and treat pipelock as an additional detection and + content-inspection layer, not the sole barrier. + +**Revised tiering:** + +- **v1 (unchanged):** in-container iptables + ipset + dnsmasq, as specified + in `network-egress-guard.md`. This closes the IP, TCP, UDP, and raw DNS + attack surface. +- **v2 (updated):** pipelock sidecar instead of smokescreen sidecar. Adds + hostname-based allowlisting, content DLP, subdomain entropy analysis, and + MCP scanning on top of the v1 IP layer. Implementation effort is comparable + to the smokescreen plan; capabilities are a strict superset for the + claude-bottle threat model. +- **DIY tripwire script (deferred):** the `secret-exfil-tripwire-encodings.md` + DIY sketch can be deferred entirely if pipelock's DLP patterns cover the + secrets in use. Custom patterns (for secrets not matching pipelock's 48 + built-ins) can be added via pipelock's signed rule bundle mechanism when + and if needed. + +--- + +## Open questions + +1. **Who is `luckyPipewrench`?** The maintainer is not publicly identified + as an individual or a named organization with a security track record. + Before relying on pipelock at a detection boundary, a code review of the + DLP matching and scanning pipeline is warranted. The repo is public under + Apache 2.0 at . + +2. **Does the pipelock Docker image introduce supply-chain risk?** + Pulling `ghcr.io/luckypipewrench/pipelock:latest` brings in a binary + from an unvetted source. Pinning by digest (as the CLAUDE.md recommends + for supply-chain hygiene) and building from source are both options. + +3. **What is the actual DLP false-positive rate for the secrets claude-bottle + agents use?** The 48 patterns cover well-known credential formats. Custom + patterns can be added but the mechanism (signed rule bundles) is not + documented in detail in public search results. Before v2, testing against + real agent traffic is needed to establish the baseline FP rate. + +4. **Does the dnsmasq layer remain necessary alongside pipelock sidecar?** + Yes, for raw UDP/53 interception. Pipelock's subdomain entropy check fires + on URLs it processes; it does not intercept DNS packets that bypass the + proxy. The controlled resolver closes that gap. Re-evaluate if pipelock + adds a DNS interception mode in a future release. + +5. **Which features are Apache 2.0 vs ELv2-only?** The repo carries an + `enterprise/` subtree under the Elastic License v2. Several features + discussed in this note (mediator-signed action receipts, signed rule + bundles, possibly some scanning passes) may live there. Before scoping + integration work, audit which capabilities cited above are in the + Apache 2.0 core and which require accepting ELv2 terms (which permit + internal use and modification but prohibit offering pipelock as a + managed service). For claude-bottle's local-Docker single-user use case, + ELv2 is likely acceptable, but the determination should be explicit. + +6. **Can pipelock's YAML config be generated per-agent from the manifest in + a way that handles the `ssh` array correctly?** The `ssh` array in + `claude-bottle.json` contains hostnames, ports, and `KnownHostKey` entries. + These need to be mapped to pipelock's `api_allowlist` (for HTTP) and + potentially to a separate bypass for the SSH socket. SSH is opaque to the + HTTP proxy and does not go through `HTTPS_PROXY`; the allowlist entry is + relevant only if the SSH host is also reached over HTTPS for key exchange + or API calls. + +--- + +## References + +- `luckyPipewrench/pipelock` GitHub: +- Pipelock project site: +- Pipelock v2.3.0 release post: +- Pipelock v2.3 upgrade guide: +- Pipelock v2.2.0 release (newreleases.io): +- Help Net Security announcement (2026-05-04): +- Pipelock configuration reference: +- Pipelock security assurance doc: +- Pipelock deployment recipes: +- Pipelock agent firewall explainer: +- Cloudflare Sandboxes + Pipelock two-layer egress: +- Pipelock vs Docker MCP Gateway comparison: +- DEV Community — AI agents leak API keys through DNS queries: +- DeepWiki entry: +- randomcpu.com writeup: +- `stripe/smokescreen` (v2 baseline): +- Anthropic `init-firewall.sh` (v1 baseline): +- Claude Code network config docs: +- Prior research — network egress guard: `docs/research/network-egress-guard.md` +- Prior research — secret exfil tripwire encodings: `docs/research/secret-exfil-tripwire-encodings.md` + +Research conducted 2026-05-08.