Files
bot-bottle/docs/research/pipelock-assessment.md
T
2026-05-28 17:56:14 -04:00

36 KiB
Raw Blame History

Pipelock assessment for bot-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 bot-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: https://github.com/luckyPipewrench/pipelock
  • Project site / documentation: https://pipelab.org/pipelock/
  • 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). 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). 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 (~1220 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). 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:443 through the proxy but embed a different SNI inside the TLS session. Pipelock supports TLS interception via its tls_interception config block (enabled, ca_cert, ca_key, cert_ttl, cert_cache_size, passthrough_domains, max_response_bytes) plus the pipelock tls init / install-ca / show-ca CLI; with interception on, the body and inner Host header become visible to its scanner pipeline, closing the domain-fronting gap. With interception off (default in the generated config), pipelock relays the CONNECT as an opaque tunnel and only sees the outer hostname.
  • 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 bot-bottle

Deployment topology

Pipelock explicitly supports two deployment shapes relevant to bot-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 bot-bottle because it matches the existing Python-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 bot-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 bot-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 bot-bottle threat model.

Runtime footprint

A single Go binary, ~1220 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 bot-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 mitigated when tls_interception is enabled (CA trust required in client) 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 lowmedium (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 bot-bottle is identical: a separate container on an internal Docker network, with the agent's HTTPS_PROXY pointing at it. The cli.py 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 bot-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.

Does pipelock make bot-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 bot-bottle provides still doing useful work?

The short answer: no, pipelock does not make bot-bottle redundant. The two operate at different layers and the overlap is narrow.

Where pipelock substitutes for parts of bot-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 bot-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". bot-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. bot-bottle's bot-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. bot-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 bot-bottle exposes is part of the per-agent isolation model, not just a configuration.

  7. Shareability of agent definitions. A bot-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 bot-bottle make pipelock redundant? Equally no. Docker container isolation does nothing about content-level exfil over an allowed channel. A misbehaving agent inside a bot-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 bot-bottle and the content-inspection argument for pipelock do not overlap.

Net conclusion

Pipelock and bot-bottle are layered defenses, not alternatives. bot-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, bot-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 bot-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 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.

  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 bot-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 bot-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 bot-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

Research conducted 2026-05-08.