c4cf2453e2c844e7955f40aa87fcf66e582b52c6
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
9cd583fbbb |
feat(egress-proxy): retarget remediation at egress-proxy (PRD 0017 chunk 3)
Finishes PRD 0017. The `cred-proxy-block` MCP tool is renamed and
its remediation apply path is repointed at egress-proxy.
- `claude_bottle/supervise.py` — `TOOL_CRED_PROXY_BLOCK` →
`TOOL_EGRESS_PROXY_BLOCK`; `COMPONENT_FOR_TOOL` maps the new
tool ID to `egress-proxy` for audit-log routing.
- `claude_bottle/supervise_server.py` — tool definition renamed
+ description rewritten: "Call when egress-proxy refused your
HTTPS request ... Read the current routes.yaml from /etc/
claude-bottle/current-config/routes.yaml, compose a modified
version, pass the full new file plus a justification." The
syntactic validator dispatches on the new tool ID.
- `claude_bottle/backend/docker/egress_proxy_apply.py` — renamed
from `cred_proxy_apply.py`. Reads routes.yaml from
/etc/egress-proxy/routes.yaml via `docker exec cat`; validates
via `egress_proxy_addon_core.load_routes` (so both sides use
the same parser); writes via `docker cp`; SIGHUPs egress-proxy
with `docker kill --signal HUP`. `EgressProxyApplyError`
replaces `CredProxyApplyError`.
- `claude_bottle/cli/dashboard.py` — wires the new apply +
`discover_egress_proxy_slugs` helper; the operator-initiated
`routes edit <bottle>` verb now writes to egress-proxy with
`.yaml` suffix. Stale follow-up comment about path-aware
filtering removed — PRD 0017 settled that question.
- `tests/integration/test_supervise_sidecar.py` — restores the
approval round-trip test (chunk 2 had switched it to a reject
path because no cred-proxy existed). Approval stubs
`apply_routes_change` so the test focuses on the supervise
queue/response plumbing rather than docker-exec into a real
egress-proxy sidecar (that's covered separately).
- `tests/unit/test_egress_proxy_apply.py` — rewritten against
the new validator; covers JSON shape, missing routes key,
partial-auth-pair rejection (the addon-core parser catches
these before SIGHUP).
- PRDs 0010 + 0014 — status headers updated to
Superseded / Retargeted with a callout block pointing at PRD
0017's migration section. Historical text preserved.
384 unit + integration tests pass.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
70f773ac61 |
feat(egress-proxy): cutover from cred-proxy (PRD 0017 chunk 2)
Hard cutover. cred-proxy is deleted; egress-proxy is now the agent's
HTTP_PROXY (when routes are declared) with pipelock on its outbound
leg. Two per-bottle CAs are minted: egress-proxy's (agent trust
store) and pipelock's (egress-proxy's outbound trust store).
Manifest:
- `bottle.cred_proxy` → hard error with a migration recipe.
- `bottle.egress_proxy` is the new shape (PRD 0017 chunk 1).
- CredProxy* types + role validators removed.
Wiring:
- launch.py: `egress_proxy_tls_init` mints the egress-proxy CA
(cert+key concat for mitmproxy + cert-only for agent trust);
`DockerEgressProxy.start` docker-cps both CAs in, sets
`HTTPS_PROXY=pipelock` + `EGRESS_PROXY_UPSTREAM_CA` so mitmdump
trusts pipelock's MITM. Agent's HTTP_PROXY points at
egress-proxy when routes exist, else falls back to pipelock
(no-routes bottles unchanged).
- prepare.py / backend.py: `cred_proxy` arg → `egress_proxy`;
sidecar-orphan probe + plan field + dashboard view all
renamed.
- provision_ca: selects the egress-proxy CA when present, else
pipelock's (filename renamed to claude-bottle-mitm-ca.crt).
- bottle.provision: cred-proxy dotfile rewrites (~/.npmrc,
~/.gitconfig insteadOf, tea config) are gone — HTTP_PROXY
catches everything respecting it.
Pipelock helpers:
- `pipelock_token_hosts` → `pipelock_route_hosts` (now reading
egress_proxy.routes).
- cred-proxy hostname auto-allow → egress-proxy hostname
auto-allow.
- Anthropic seed-phrase workaround now triggers when an
egress_proxy route targets api.anthropic.com (was based on the
cred-proxy `anthropic-base-url` role).
Dockerfile.egress-proxy:
- Entrypoint conditionally passes
`--set ssl_verify_upstream_trusted_ca=$EGRESS_PROXY_UPSTREAM_CA`
(via the `${VAR:+...}` shell expansion) so standalone runs without
a mounted pipelock CA still boot.
- mkdirs `/home/mitmproxy/.mitmproxy` ahead of `docker cp`.
Deleted: claude_bottle/{cred_proxy,cred_proxy_server}.py,
backend/docker/{cred_proxy,provision/cred_proxy}.py,
Dockerfile.cred-proxy, plus the corresponding unit + integration
tests. backend/docker/cred_proxy_apply.py stays as a stub for
chunk 3 to rewrite (its container-name + routes-path constants
are inlined so it survives without the deleted module).
Test changes:
- test_pipelock_allowlist rewritten against egress-proxy routes
+ the new `pipelock_route_hosts`.
- test_manifest_md_load + test_pipelock_yaml + test_yaml_subset
fixtures migrated to the `egress_proxy: { routes: [...] }`
shape.
- test_supervise_sidecar's round-trip test switched from
`dashboard.approve` to `dashboard.reject`: the approval-apply
path on cred-proxy-block proposals hits a deleted sidecar in
chunk 2's transitional state. Chunk 3 restores the approval
test once the remediation flow is retargeted at egress-proxy.
376 tests pass (was 427; net delta is removed cred-proxy tests).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
|
||
|
|
92fee89e20 |
test(supervise): skip queue round-trip test in docker-in-docker (PRD 0013)
The integration test test_tools_call_round_trips_through_queue relies on a host bind-mount to share the queue dir between the sidecar (writing proposals) and the test process (approving via dashboard helpers). In the Gitea Actions runner the docker socket forwards to the outer host's daemon, so bind-mount paths are resolved against the outer host's fs — not the runner container's. The sidecar writes its proposal where the test can't see it; the test times out. Add a one-shot probe that does docker run -v <tmp>:<container> and checks both directions of fs visibility. Skip the round-trip test when the probe fails. tools_list and the orphan-name test are unaffected — they don't touch the queue. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |
||
|
|
9f445d61be |
test(supervise): docker integration test for the sidecar (PRD 0013)
Phase 5 of PRD 0013. End-to-end integration test against real Docker: - Brings up the supervise sidecar on a per-bottle internal network. - A curl-image "agent" on the same network does tools/list and gets back the three PRD 0013 tool names over real MCP wire format. - A tools/call round-trips through the queue: agent blocks on the call, host watches the queue, dashboard.approve writes a Response, agent receives the approval payload (status, notes) in MCP content. - Documents the orphan-sidecar name-collision behavior so a future auto-cleanup change can flip the assertion. Skips if docker is unreachable, matching the existing integration pattern. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> |