[Bug] Tool-scoped deny rules override sandbox network isolation at network level

Resolved 💬 2 comments Opened Mar 25, 2026 by dolodort Closed Apr 24, 2026

Bug Description

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [ ] I am using the latest version of Claude Code

What's Wrong?

Adding a tool-scoped deny rule like WebFetch(domain:github.com) to permissions.deny in .claude/settings.json causes the sandbox to block all network access to that domain — not just WebFetch tool calls. This breaks git push, git pull, git fetch, and any other operation that makes HTTPS connections to the denied domain.

The deny rule syntax WebFetch(domain:X) implies tool-level scoping (only the WebFetch tool should be affected), but at runtime it appears to be enforced as a network-level block in the sandbox proxy, effectively adding the domain to a denied hosts list. This overrides sandbox.network.allowedDomains even when the domain is explicitly listed there.

What Should Happen?

WebFetch(domain:github.com) in permissions.deny should only prevent the WebFetch tool from accessing github.com. Other tools and network operations — git over HTTPS, gh CLI calls, Bash commands — should remain unaffected.

When a domain appears in both sandbox.network.allowedDomains and a WebFetch(domain:...) deny rule, the sandbox should allow network traffic to that domain while blocking only the WebFetch tool from using it.

Error Messages/Logs

$ git push -u origin sandbox-beads
fatal: unable to access 'https://github.com/snowpackdata/tessellate.git/': CONNECT tunnel failed, response 403

The 403 from CONNECT tunnel failed indicates the sandbox HTTPS proxy is rejecting the connection at the network level, not that GitHub is returning a 403.

Steps to Reproduce

  1. Start with a working sandbox configuration where github.com is in allowedDomains and git push works:
{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "enableWeakerNetworkIsolation": true,
    "network": {
      "allowedDomains": [
        "github.com",
        "api.github.com",
        "uploads.github.com"
      ]
    }
  },
  "permissions": {
    "deny": []
  }
}
  1. Confirm git push works in a Claude Code session (Bash tool)
  2. Add a WebFetch-scoped deny rule:
{
  "permissions": {
    "deny": [
      "WebFetch(domain:github.com)"
    ]
  }
}
  1. Start a new Claude Code session (settings reload on session start)
  2. Ask Claude to run git push via the Bash tool
  3. Observe: CONNECT tunnel failed, response 403
  4. Remove the WebFetch(domain:github.com) deny rule, restart session
  5. git push works again immediately — no other changes needed

Runtime sandbox state

When the deny rule was active, the runtime sandbox config injected into the session showed:

Network: {
  "allowedHosts": ["github.com", "api.github.com", ...],
  "deniedHosts": ["github.com", "raw.githubusercontent.com"]
}

The deniedHosts array does not exist in our settings.json — it was synthesized at runtime from the WebFetch(domain:...) deny rules. Since denied hosts override allowed hosts, all network access to github.com was blocked.

Is this a regression?

I don't know

Claude Code Version

2.1.81 (Claude Code)

Platform

Anthropic API

Operating System

macOS 15.5 (Build 24F74), Apple Silicon (arm64)

Terminal/Shell

Ghostty

Additional Information

Full sandbox configuration (working state, after removing the deny rule)

{
  "sandbox": {
    "enabled": true,
    "autoAllowBashIfSandboxed": true,
    "allowUnsandboxedCommands": false,
    "enableWeakerNetworkIsolation": true,
    "excludedCommands": ["docker", "docker-compose", "subl"],
    "filesystem": {
      "allowRead": ["~/.docker/config.json", "~/.ssh/known_hosts", ".env"],
      "allowWrite": ["~/bin", "/tmp", "/private/tmp", "~/.bun", "~/.tessellate", "~/Snowpack Data Downloads"]
    },
    "network": {
      "allowedDomains": [
        "github.com", "api.github.com", "uploads.github.com",
        "registry.npmjs.org", "api.anthropic.com", "code.claude.com",
        "docs.anthropic.com", "snowpack-data.com", "localhost"
      ],
      "allowUnixSockets": ["~/.docker/run/docker.sock"],
      "allowLocalBinding": true
    }
  }
}

Use case

We use Claude Code with a comprehensive sandbox configuration for a multi-agent development workflow. We added WebFetch(domain:github.com) to `permissi…
Note: Content was truncated.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗