Cleans up references to the pre-refactor bash layout (cli.sh, lib/*.sh, scripts/*.sh) across README, Dockerfile, the pipelock PRD, and research notes. Refreshes line numbers in the oauth-token note against the current cli/start.py. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
35 KiB
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-effortmode, which relies onHTTPS_PROXYenv 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-effortdegradation problem entirely. - Recommendation: skip pipelock as an in-container self-contained guard
(the
--best-effortcaveat 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: https://github.com/luckyPipewrench/pipelock
- Project site / documentation: https://pipelab.org/pipelock/
- Maintainer:
luckyPipewrench(GitHub org); also associated with thepipelab.orgdomain. 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 andLICENSElayout in the project README (README). Which capabilities sit on which side of that line is a question this note does not answer; before adoption, theenterprise/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). An accompanying Help Net Security announcement appeared 2026-05-04 (helpnetsecurity.com); 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), andgo 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).
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/). 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).
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).
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/).
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/, 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
(<pl:aws-access-key:1>, 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/).
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:443through 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 innetwork-egress-guard.mdas 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).
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.py 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)
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).
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:
-
It replaces smokescreen with a strict superset. Pipelock covers everything smokescreen covers (CONNECT-based hostname allowlisting, RFC 1918 blocking, Docker
--internalnetwork 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'sHTTPS_PROXYpointing at it. Thecli.pychanges are the same pattern. -
The DLP layer is the most direct answer to the content-tripwire gap. The
secret-exfil-tripwire-encodings.mdnote 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. -
The
--best-effortproblem 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--internalflag at the LinuxKit level, not by pipelock's in-process sandbox. -
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. -
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
luckyPipewrenchorg 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.mdDIY 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.
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:
-
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$HOMEexcept what was deliberately copied in is materially stronger than a Landlock-restricted view of the host filesystem. -
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 -- claudefour 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. -
The manifest model. claude-bottle's
claude-bottle.jsoncarries per-agentenv,skills,prompt, andsshconfiguration 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. -
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.
-
The SSH-agent-in-container design. The agent socket runs as root inside the container, the keys are deleted from disk after loading, and
socatproxies 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 thenodeuser 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. -
Skill-directory injection per agent. The
skillsarray 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. -
Shareability of agent definitions. A
claude-bottle.jsonfile 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
-
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 https://github.com/luckyPipewrench/pipelock. -
Does the pipelock Docker image introduce supply-chain risk? Pulling
ghcr.io/luckypipewrench/pipelock:latestbrings 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. -
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.
-
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.
-
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. -
Can pipelock's YAML config be generated per-agent from the manifest in a way that handles the
ssharray correctly? Thessharray inclaude-bottle.jsoncontains hostnames, ports, andKnownHostKeyentries. These need to be mapped to pipelock'sapi_allowlist(for HTTP) and potentially to a separate bypass for the SSH socket. SSH is opaque to the HTTP proxy and does not go throughHTTPS_PROXY; the allowlist entry is relevant only if the SSH host is also reached over HTTPS for key exchange or API calls.
References
luckyPipewrench/pipelockGitHub: https://github.com/luckyPipewrench/pipelock- Pipelock project site: https://pipelab.org/pipelock/
- Pipelock v2.3.0 release post: https://pipelab.org/blog/pipelock-v230-release/
- Pipelock v2.3 upgrade guide: https://pipelab.org/learn/pipelock-v230-upgrade/
- Pipelock v2.2.0 release (newreleases.io): https://newreleases.io/project/github/luckyPipewrench/pipelock/release/v2.2.0
- Help Net Security announcement (2026-05-04): https://www.helpnetsecurity.com/2026/05/04/pipelock-open-source-ai-agent-firewall/
- Pipelock configuration reference: https://github.com/luckyPipewrench/pipelock/blob/main/docs/configuration.md
- Pipelock security assurance doc: https://github.com/luckyPipewrench/pipelock/blob/main/docs/security-assurance.md
- Pipelock deployment recipes: https://github.com/luckyPipewrench/pipelock/blob/main/docs/guides/deployment-recipes.md
- Pipelock agent firewall explainer: https://pipelab.org/agent-firewall/
- Cloudflare Sandboxes + Pipelock two-layer egress: https://pipelab.org/learn/cloudflare-sandboxes-pipelock/
- Pipelock vs Docker MCP Gateway comparison: https://pipelab.org/compare/pipelock-vs-docker-mcp-gateway/
- DEV Community — AI agents leak API keys through DNS queries: https://dev.to/luckypipewrench/your-ai-agent-leaks-api-keys-through-dns-queries-5c1d
- DeepWiki entry: https://deepwiki.com/luckyPipewrench/pipelock
- randomcpu.com writeup: https://randomcpu.com/pipelock-agent-firewall-for-ai-coding-tools/
stripe/smokescreen(v2 baseline): https://github.com/stripe/smokescreen- Anthropic
init-firewall.sh(v1 baseline): https://github.com/anthropics/claude-code/blob/main/.devcontainer/init-firewall.sh - Claude Code network config docs: https://code.claude.com/docs/en/network-config
- 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.