feat(egress-proxy): mitmproxy sidecar core (PRD 0017 chunk 1) #28
Reference in New Issue
Block a user
Delete Branch "egress-proxy-sidecar-core"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Chunk 1 of PRD 0017 (docs/prds/0017-egress-proxy-via-mitmproxy.md). Lands the new egress-proxy artifact alongside cred-proxy without yet displacing it. Chunk 2 cuts agent HTTP_PROXY over and removes cred-proxy; chunk 3 retargets PRD 0014 remediation.
What's in the box:
Dockerfile.egress-proxy— mitmproxy 11.1.3 base, addon copied flat to/app, routes dir pre-created at/etc/egress-proxy/. Digest pin deferred to chunk 2 (TODO marker in the Dockerfile).egress_proxy_addon_core.py— pure parse + decide logic. Stdlib only. 21 host-importable unit tests cover host-only / full-route / partial-auth-reject / path-allowlist enforcement / case-insensitive host match / Bearer + token schemes / empty + missing token-env behaviour.egress_proxy_addon.py— mitmproxy hook wrapper. Boot + SIGHUP reload of routes.yaml; on each request strips Authorization, callsdecide(), returns 403 or injects header. Importsmitmproxyso it's container-only; uses absolute import (from egress_proxy_addon_core) because both files land flat in/app.claude_bottle/egress_proxy.py— host helpers: route lift from manifest, token-env-map derivation, routes.yaml render (JSON content, .yaml extension per PRD),EgressProxyabstract class withprepare().backend/docker/egress_proxy.py—DockerEgressProxystart/stop mirroringDockerCredProxy's shape. Not yet called fromlaunch.py; chunk 2 wires it in.manifest.py—EgressProxyRoute+EgressProxyConfigwith the nestedauth: { scheme, token_ref }block. Emptyauth: {}is an error per PRD.egress_proxyjoins the bottle key set;cred_proxystays (chunk 2 hard-fails on it).Validated locally:
python3 -m unittest discover -s tests/unit— 427 pass (62 of them are new).docker build -f Dockerfile.egress-proxy .succeeds.docker run claude-bottle-egress-proxy:testboots mitmdump; with a mounted routes.yaml the addon logsloaded 2 route(s): api.example.com, x.example.Notes for review:
.yamlfilename per the PRD's/etc/egress-proxy/routes.yamlpath. Every JSON document is valid YAML, and stdlibjsonworks on both ends.mitmproxy/mitmproxy:11.1.3. Chunk 2 (which moves the pipelock CA over and starts wiring TLS through this image) is the natural place to lock in the digest after we've shaken anything loose.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>didericis referenced this pull request2026-05-25 14:31:13 -04:00