3df54573d4
Lands the new egress-proxy artifact alongside cred-proxy. Chunk 2
wires the agent's HTTP_PROXY to it and removes cred-proxy.
- `Dockerfile.egress-proxy` — mitmproxy 11.1.3 base, COPY addon
files flat to /app, mkdir routes dir at /etc/egress-proxy/.
Digest pin deferred to chunk 2.
- `egress_proxy_addon_core.py` — pure-logic parse + decide
(host-importable; 21 unit tests).
- `egress_proxy_addon.py` — mitmproxy hook wrapper, container-only
(boot + SIGHUP reload, strip-Authorization + decide + 403/inject).
- `egress_proxy.py` — host helpers: manifest lift, routes.yaml
render (JSON content), token-env-map, Plan + abstract class.
- `backend/docker/egress_proxy.py` — `DockerEgressProxy` start/stop
mirroring `DockerCredProxy`; not yet called from launch.py.
- `manifest.py` — new `EgressProxyRoute` + `EgressProxyConfig` types
with the nested `auth: { scheme, token_ref }` block per PRD;
`bottle.egress_proxy` added to the bottle key set alongside
`cred_proxy` (chunk 2 hard-fails on the latter).
All 427 unit tests pass. Image builds; `docker run` boots mitmdump
and the addon loads routes from a mounted routes.yaml.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
48 lines
2.1 KiB
Docker
48 lines
2.1 KiB
Docker
# Per-bottle egress-proxy sidecar image (PRD 0017).
|
|
#
|
|
# Replaces cred-proxy (PRD 0010). Sits on the agent's HTTP_PROXY /
|
|
# HTTPS_PROXY path (wiring lands in chunk 2) and owns three jobs:
|
|
# 1. MITM HTTPS using the per-bottle CA (chunk 2 moves the CA
|
|
# generation from pipelock).
|
|
# 2. Enforce manifest-declared path_allowlist per route.
|
|
# 3. Inject Authorization headers for routes that declare an auth
|
|
# block.
|
|
#
|
|
# Chunk 1 of PRD 0017 ships this image and the addon. Wiring it
|
|
# into the bottle launch (and the per-bottle CA + the pipelock
|
|
# upstream proxy) is chunk 2.
|
|
|
|
# mitmproxy base image. mitmdump + addon API are already there; we
|
|
# only need to drop our addon in. TODO(chunk-2): pin by digest.
|
|
FROM mitmproxy/mitmproxy:11.1.3
|
|
|
|
USER root
|
|
|
|
# The addon ships as two files. `_core.py` is pure-logic, importable
|
|
# both inside the container and from the host's tests; `_addon.py` is
|
|
# the mitmproxy hook wrapper. Both land flat in /app/ so mitmdump's
|
|
# loader finds them as top-level sibling modules.
|
|
COPY claude_bottle/egress_proxy_addon_core.py /app/egress_proxy_addon_core.py
|
|
COPY claude_bottle/egress_proxy_addon.py /app/egress_proxy_addon.py
|
|
|
|
# Pre-create the runtime directory the backend's start step will
|
|
# `docker cp` routes.yaml into. docker cp does not create
|
|
# intermediate dirs, so the mkdir must be baked into the image.
|
|
# Ownership lets the unprivileged mitmproxy user read the file.
|
|
RUN mkdir -p /etc/egress-proxy \
|
|
&& chown -R mitmproxy:mitmproxy /etc/egress-proxy /app
|
|
|
|
USER mitmproxy
|
|
|
|
# Listening port. Agents will dial egress-proxy on this port via
|
|
# their HTTP_PROXY env (chunk 2). Surfaced as EXPOSE for
|
|
# documentation; not required for the internal network to route to it.
|
|
EXPOSE 9099
|
|
|
|
# --mode regular@9099: standard HTTP/HTTPS forward proxy on :9099.
|
|
# -s /app/egress_proxy_addon.py: loads our addon, which reads the
|
|
# route table from /etc/egress-proxy/routes.yaml.
|
|
# (Upstream-trust + CA-cert hooks land in chunk 2 when the per-bottle
|
|
# pipelock CA wiring moves over from cred-proxy.)
|
|
ENTRYPOINT ["mitmdump", "--mode", "regular@9099", "-s", "/app/egress_proxy_addon.py"]
|