Cloud sandbox: agent-proxy signs with a staging CA that has no X.509v3 extensions, breaking every Python 3.13+ client

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 17, 2026

Summary

In a cloud sandbox session, the local agent-proxy re-terminates TLS using CN = CCR Upstream Proxy CA (staging), O = Anthropic. That certificate is self-signed and openssl x509 reports No extensions in certificate — no basicConstraints, no keyUsage.

RFC 5280 §4.2.1.3 requires keyUsage on a CA certificate, and Python 3.13 turned on ssl.VERIFY_X509_STRICT by default in create_default_context(). So every Python ≥ 3.13 HTTPS client in the sandbox fails, while curl, Node and Go succeed against the same host — they do not enforce that constraint.

/root/.ccr/README.md instructs every tool to trust /root/.ccr/ca-bundle.crt. For Python 3.13+ that instruction cannot succeed: trusting a malformed CA is precisely the operation that fails.

There is a second, separate oddity: a staging CA is intercepting a production session, while a conformant production CA sits unused in the same bundle.

Environment

  • Cloud sandbox session (org-shared cloud environment, Trusted network access), Ubuntu 24.04 x86_64
  • python 3.13, httpx 0.28.1 (default verify=True, trust_env=True)
  • SSL_CERT_FILE=/root/.ccr/ca-bundle.crt, HTTPS_PROXY=http://127.0.0.1:<port>

What happens

httpx.ConnectError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed:
CA cert does not include key usage extension (_ssl.c:1032)

Identical with SSL_CERT_FILE pointing at /root/.ccr/ca-bundle.crt or at /etc/ssl/certs/ca-certificates.crt. curl -o /dev/null -w '%{http_code}' https://api.<redacted>.com/api/health/ on the same host, same session: 200.

Evidence

/root/.ccr/ contains README.md, agent-proxy-ca.crt, ca-bundle.crt, java-truststore.p12. The two CAs in agent-proxy-ca.crt:

subject=CN = CCR Upstream Proxy CA (staging), O = Anthropic
issuer=CN = CCR Upstream Proxy CA (staging), O = Anthropic
X509v3 Basic Constraints: critical
    CA:TRUE
                                    <-- no keyUsage

subject=CN = CCR agent-proxy interception CA (production) 2026-08, O = Anthropic
issuer=CN = CCR agent-proxy interception CA (production) 2026-08, O = Anthropic
X509v3 Basic Constraints: critical
    CA:TRUE
X509v3 Key Usage: critical
    Certificate Sign            <-- conformant, and NOT the one signing

The chain actually presented through the local proxy (openssl s_client -proxy 127.0.0.1:<port> -connect <host>:443 -showcerts):

subject=CN = api.<redacted>.com
issuer=CN = CCR Upstream Proxy CA (staging), O = Anthropic
X509v3 Key Usage: critical
    Digital Signature, Key Encipherment

No extensions in certificate
subject=CN = CCR Upstream Proxy CA (staging), O = Anthropic
issuer=CN = CCR Upstream Proxy CA (staging), O = Anthropic

For contrast, the chain presented by the upstream egress gateway (same host, connecting without the local proxy) is conformant end to end — all three certificates carry keyUsage:

CN = *.<redacted>.com
  <- O = Anthropic, CN = Egress Gateway SDS Issuing CA (production)   keyUsage: Certificate Sign, CRL Sign
  <- O = Anthropic, CN = sandbox-egress-gateway-production Egress Gateway CA   keyUsage: Certificate Sign, CRL Sign

curl -sS http://127.0.0.1:<port>/__agentproxy/status reports "enabled": true, "caBundlePath": "/root/.ccr/ca-bundle.crt", "hasSystemCa": true, "recentRelayFailures": [] — the proxy itself sees nothing wrong, because the rejection happens client-side.

Impact

Any Python ≥ 3.13 client using httpx, requests or urllib with a default SSL context. That is most Python tooling in a sandbox as 3.13 becomes the default interpreter, and the failure surfaces as a generic connection error, so it reads as "the API is down" rather than "the proxy CA is malformed". It cost us most of a day.

What we tried

| Attempt | Result |
|---|---|
| SSL_CERT_FILE=/root/.ccr/ca-bundle.crt (as the README prescribes) | Same failure |
| SSL_CERT_FILE pointing at only the conformant production CA from that bundle | Same failure — it is not the signing CA |
| NO_PROXY=<host> set in the cloud environment's variables, to reach the conformant gateway chain instead | Not possible: the sandbox rewrites NO_PROXY after the environment's variables are applied, so the entry is dropped. It works when set per command, which is not a configuration. |

Our workaround is to clear ssl.VERIFY_X509_STRICT on that one client's context, keeping verify_mode=CERT_REQUIRED and check_hostname=True. It is a workaround for a malformed certificate, in shipped code, which is why we would rather it disappear.

Expected

  1. The agent-proxy interception CA carries keyUsage = keyCertSign, cRLSign (and basicConstraints: critical, CA:TRUE), so /root/.ccr/ca-bundle.crt can be trusted by a conforming client — which is what the README already tells every tool to do.
  2. A production session is intercepted by the production CA, not by the staging one.

Happy to run any further diagnostic in the same environment.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗