[BUG] Allow network egress - All domains' setting not reflected in session proxy JWT
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Summary
When Allow network egress is enabled with Domain allowlist set to All
domains, the egress proxy still enforces a restrictive hardcoded allowlist of
specific domains rather than permitting all outbound traffic.
Actual Behavior
The egress proxy returns 403 Forbidden with x-deny-reason: host_not_allowed.
Inspecting the proxy's https_proxy JWT (visible in curl -v output) reveals
the token contains an explicit allowed_hosts field listing specific well-known
package registries and development services — not a wildcard. The "All domains"
setting is not reflected in the issued JWT.
Additional Context
- The setting has been configured for multiple weeks, ruling out a propagation delay
- Starting a new session does not resolve the issue — the JWT is still minted
with the restrictive allowlist
- The JWT has
iat/expfields confirming it is issued at session start,
suggesting session initialization does not correctly read the current allowlist policy
Impact
Users with legitimate use cases requiring access to private/self-hosted
infrastructure (e.g., internal services, private registries, on-prem tooling)
are blocked even after explicitly configuring unrestricted egress access.
What Should Happen?
All outbound domains should be accessible, as indicated by the UI message:
"Claude can access all domains on the internet."
Error Messages/Logs
$ curl -v --max-time 10 https://<custom-domain>/api/v1/version
* Uses proxy env variable https_proxy == 'http://...jwt_<token>...'
* Trying 21.0.0.191:15004...
* Connected to 21.0.0.191 port 15004
* CONNECT tunnel: HTTP/1.1 negotiated
* Establish HTTP proxy tunnel to <custom-domain>:443
> CONNECT <custom-domain>:443 HTTP/1.1
< HTTP/1.1 403 Forbidden
< x-deny-reason: host_not_allowed
< server: envoy
* CONNECT tunnel failed, response 403
curl: (56) CONNECT tunnel failed, response 403
{
"iss": "anthropic-egress-control",
"iat": 1773591510, // 2026-03-15 16:18:30 UTC
"exp": 1773605910, // 2026-03-15 20:18:30 UTC
"allowed_hosts_count": 205,
"allowed_hosts": ["java.net", "registry.yarnpkg.com", "get.rvm.io", "k8s.io",
"*.googleapis.com", "java.com", "www.rust-lang.org", ...],
"wildcard_entries": ["*.googleapis.com", "*.nixos.org", "*.sentry.io",
"*.microsoftonline.com", "*.amazonaws.com", ...],
"use_egress_gateway": true
}
Steps to Reproduce
- In Claude Code settings, enable Allow network egress
- Set Domain allowlist to All domains
- Save settings
- Start a new conversation session
- Attempt to make an outbound HTTP request to a domain not on the standard
package registry allowlist (e.g., a private self-hosted service)
Claude Model
Sonnet (default)
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
Claude 1.1.6679 (f8f4ff) 2026-03-13T18:26:03.000Z
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
PowerShell
Additional Information
Key observation: allowed_hosts contains a fixed list of 205 specific domains/patterns. There is no * wildcard, no allow_all: true flag, and no indication that the "All domains" UI setting is reflected anywhere in the token. A custom self-hosted domain is rejected with host_not_allowed despite the org setting being configured to "All domains" for over two weeks and across multiple reinstalls/sessions.
Showing cached comments. Read the full discussion on GitHub ↗
3 Comments
Adding some observations that might help narrow this down:
I'm running Cowork on macOS. A few data points:
Subdomain asymmetry on GitHub:
github.com (main web interface) — accessible via WebFetch ✅
raw.githubusercontent.com — blocked ❌
api.github.com — blocked ❌
This suggests the hardcoded allowlist includes github.com but not its subdomains, which would be consistent with the JWT containing exact hostnames rather than wildcard entries like *.github.com.
Government/public-sector domains blocked:
ontario.ca (Ontario government website, Canada) — blocked ❌
This is a legitimate use case — fetching publicly available government documents and schedules.
Regression note:
I had a scheduled task (running in Cowork) that successfully fetched a page on ontario.ca for several weeks. It stopped working at some point — I don't have the exact date, but this suggests the allowlist may have become more restrictive over time, not less.
Environment: Cowork macOS, April 2026. Network egress set to "All domains" in Admin → Capabilities — this setting has no effect on the proxy behaviour as described in this issue.
Confirming this on Claude Code on the web (cloud sessions, both scheduled routines and manual runs), 2026-08-09. Same root cause, slightly different surface — posting the raw proxy exchange since it differs from the JWT symptom above.
Configuration: Allow network egress enabled, Domain allowlist = All domains, UI states "Claude can access all domains on the internet." Individual (non-Team) account.
Result: every non-package-manager host is rejected at CONNECT.
The 36-byte body of the CONNECT response (read off a raw socket):
Note: in this environment the proxy sends no
x-deny-reasonheader — the denial reason exists only in that body, which makes the failure harder to diagnose than the header-based case described in the original report.WebFetchsurfaces it as:$HTTPS_PROXY/__agentproxy/statuscorroborates:Tested hosts:
www.litcharts.com,www.gutenberg.org,wolnelektury.pl— all 403. Control:pypi.org/simple/returns 200, but only because it sits inNO_PROXYand bypasses the filtering proxy entirely, so it is not evidence of working egress. The effective allowlist appears hardcoded to npm/PyPI/crates/Go/GitHub plus Anthropic domains, regardless of the account setting.Impact: agents that rely on
WebFetchto read primary sources cannot fetch a single one in cloud sessions.WebSearchstill works, but returns titles/URLs/snippets only — the pages behind those URLs are unreachable. For any workflow whose correctness depends on reading sources rather than search snippets, unattended cloud runs silently degrade to snippet-based output. In our case this produced a measurable ~12% error rate on checkable claims versus the same pipeline run locally, whereWebFetchworks normally.Happy to supply further diagnostics from a cloud session if useful.
Follow-up, ruling out the obvious alternative explanation: the target sites are not blocking the requests.
Same three URLs, same
WebFetchtool, run from a local Claude Code session minutes after the cloud test — all three succeed:| URL | cloud session | local session |
|---|---|---|
|
https://www.litcharts.com/lit/hamlet|EGRESS_BLOCKED/ CONNECT 403 | 200, page content returned ||
https://www.gutenberg.org/cache/epub/1524/pg1524.txt|EGRESS_BLOCKED/ CONNECT 403 | 200, full text returned ||
https://wolnelektury.pl/katalog/lektura/hamlet.html|EGRESS_BLOCKED/ CONNECT 403 | 200, metadata returned |The only variable is the execution environment.
Two further points that rule out site-side blocking on their own:
CONNECT www.litcharts.com:443sent to127.0.0.1:37813, i.e. before any TLS handshake with the origin server exists. A remote host cannot answer a CONNECT — that exchange is strictly between client and proxy.request rejected: host not permitted, and the harness classifies it asEGRESS_BLOCKEDwith the message "blocked by the network egress proxy".For completeness: in the same local session, verification agents fetched dozens of pages from
folger.edu,shakespeare.mit.edu,pl.wikisource.organdwolnelektury.plwithout a single block — so this is not rate limiting or bot detection against this client either.