Re-grounds the design after walking the eight original open
questions interactively. Two structural changes:
- Topology A → A'. A spike confirmed mitmproxy's `upstream` mode
re-wraps decrypted flows in a new CONNECT to the upstream proxy,
which would have left pipelock seeing only ciphertext (the very
gap this PRD set out to close). The fix is to run mitmproxy in
`regular` mode and ship a vendored Python addon that forwards
each decrypted request to pipelock as a plain HTTP forward-proxy
call. Pipelock is unchanged.
- mitmproxy owns CA generation. The research note's preference
for a host-side openssl / cryptography CA turned out to be
unnecessary — mitmproxy generates a fresh CA on startup; the
public cert is `docker cp`'d into the agent. No new host-side
crypto deps. Dry-run can't render a fingerprint (CA doesn't
exist yet); launches print it once to stderr.
Other Q3–Q8 resolutions folded in: Debian-base `update-ca-certificates`
confirmed, mitmproxy 12 verified to speak h2 on both halves,
selective-bump deferred to v2, response-body and MCP scanning
deferred to v2, domain-fronting deferred to v2.
Open questions rewritten — what remains is addon-implementation
specifics (pipelock 403-body fingerprint, env-var inheritance
through docker exec, addon test fixtures).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Captures the design for putting a mitmproxy sidecar in front of
pipelock on the egress path so pipelock's body / header / MCP
scanners see plaintext for the HTTPS hosts in the default allowlist.
Implements Topology A from docs/research/tls-mitm-for-pipelock.md
with a per-bottle ephemeral CA, no manifest schema change in v1,
and selective-bumping deferred until a pinning host appears.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Renames the file and rewrites the body around what actually shipped:
class-based BottleBackend ABC (not a free create_docker_bottle
function), the two-phase prepare/launch split, the backend/docker/
subpackage layout, env.py reshaped into a backend-neutral ResolvedEnv,
and PipelockProxy split between top-level and backend/docker/.
Across the package:
- claude_bottle/platform/ -> claude_bottle/backend/
- platform/docker/platform.py -> backend/docker/backend.py
- class BottlePlatform -> BottleBackend
- class DockerBottlePlatform -> DockerBottleBackend
- get_bottle_platform() -> get_bottle_backend()
- env var CLAUDE_BOTTLE_PLATFORM -> CLAUDE_BOTTLE_BACKEND
- dict _PLATFORMS -> _BACKENDS
"Backend" is shorter and more established as the term for a
pluggable strategy-pattern implementation. "Platform" was vague
(could mean OS, hardware, cloud) and mildly redundant — Docker is
itself a platform.
The previous PRD section claiming "the Backend protocol was
rejected" referred to a low-level run/exec/cp/network_connect
protocol; the name was never the reason. The PRD is updated to
describe that rejected design by shape rather than by name.
The bottle/agent concepts and the manifest schema are unchanged.
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>