fix(pipelock): auto-allow cred-proxy hostname when routes are declared
test / unit (pull_request) Successful in 13s
test / integration (pull_request) Successful in 22s

The agent's HTTP_PROXY env points at pipelock, so an
ANTHROPIC_BASE_URL like http://cred-proxy:9099/anthropic doesn't
short-circuit through Docker's embedded DNS — it gets forwarded
through pipelock, which then checks its api_allowlist for the
hostname `cred-proxy` and 403's because the name isn't there. The
agent surfaces the failure as "API Error: 403 blocked: domain not
in allowlist: cred-proxy" on Claude's first call.

Fix: pipelock_effective_allowlist auto-adds CRED_PROXY_HOSTNAME
when bottle.cred_proxy.routes is non-empty (i.e., when the
sidecar will actually be running and reachable).

Move CRED_PROXY_HOSTNAME from backend/docker/cred_proxy.py to the
backend-agnostic claude_bottle/cred_proxy.py so pipelock can
reference it without a layering violation; the docker concrete
imports it from the same place.
This commit is contained in:
2026-05-24 13:25:21 -04:00
parent 32b62cbacc
commit f4452b391d
4 changed files with 42 additions and 11 deletions
+16
View File
@@ -75,6 +75,22 @@ class TestAllowlistWithTokens(unittest.TestCase):
self.assertIn("registry.npmjs.org", eff)
self.assertIn("api.github.com", eff)
def test_cred_proxy_hostname_auto_added_when_routes_exist(self):
# The agent's HTTP_PROXY points at pipelock, so a request for
# http://cred-proxy:9099/... arrives at pipelock as a request
# for hostname `cred-proxy`. pipelock must allow it or the
# agent can't reach its own sidecar.
eff = pipelock_effective_allowlist(_bottle(_routes([
{"path": "/x/", "upstream": "https://x.example",
"auth_scheme": "Bearer", "token_ref": "T"},
])))
self.assertIn("cred-proxy", eff)
def test_cred_proxy_hostname_NOT_added_when_no_routes(self):
# No cred-proxy sidecar, no auto-allow.
eff = pipelock_effective_allowlist(_bottle({}))
self.assertNotIn("cred-proxy", eff)
class TestTlsPassthrough(unittest.TestCase):
def test_default_includes_api_anthropic(self):