Skip to main content
The --sandbox flag runs the CLI with OS-level isolation, enforcing the active Read and Write permission scopes at the operating-system level and optionally restricting network traffic.

How the sandbox works

When the sandbox is active:
  • Writable paths are derived from granted Write(...) permission scopes plus the workspace directory
  • Readable paths are derived from granted Read(...) scopes (platform defaults like /usr/bin are always readable)
  • Scopes granted mid-session dynamically expand the sandbox for subsequent commands
If sandbox resolution fails (e.g., the sandboxing tools are unavailable on the user’s platform), the CLI will refuse to start rather than running unsandboxed. This fail-closed behavior applies whether sandbox was enabled by a team setting or by the user passing --sandbox directly, ensuring the security intent is never silently bypassed.Common causes of sandbox resolution failure:
  • Windows: OS-level sandboxing is not currently supported on Windows. Sessions on Windows will hard-fail when --sandbox is passed or when sandbox enforcement is Required, including when the CLI runs as an ACP server inside an IDE (e.g., Devin Desktop).
  • Linux: Sandboxing requires bubblewrap (bwrap) and socat to be installed. Sessions hard-fail with installation instructions when these are missing.
  • Permission scope errors: Invalid paths in permission scopes that can’t be resolved.

Network filtering

Sandbox network filtering is currently unstable. If you need this feature, please reach out to your account representative for stability timelines.
Configure domain-level network filtering for the sandbox in the sandbox section of your config file (user config only). When --sandbox is active and domain filtering is configured, a managed network proxy starts on loopback and the sandbox restricts all child traffic to route through it.
OptionTypeDefaultDescription
allowed_domainsstring[][]Domain patterns allowed through the proxy. When non-empty, only matching domains are allowed (allowlist mode)
denied_domainsstring[][]Domain patterns always blocked. Deny rules take precedence over allow rules
network_modestring"full""full" allows all HTTP methods; "limited" allows only GET/HEAD/OPTIONS
Domain pattern syntax:
PatternMatches
example.comExact match only
*.example.comAny subdomain (not the apex)
**.example.comApex domain and any subdomain
Example:
{
  "sandbox": {
    "allowed_domains": [
      "github.com",
      "**.npmjs.org",
      "**.crates.io",
      "**.pypi.org"
    ],
    "denied_domains": ["evil.example.com"],
    "network_mode": "full"
  }
}
Domain filtering applies when the sandbox is active (--sandbox). Without --sandbox, the sandbox section is ignored.

Excluded commands

Sometimes a specific command needs to run outside the sandbox — for example git commands that must access credentials or hooks the sandbox blocks. The sandbox.excluded config section lets you exclude matching commands from sandbox isolation using the same Exec(...) rule syntax as permissions:
OptionTypeDescription
excluded.allowstring[]Matching commands run outside the sandbox automatically
excluded.askstring[]Matching commands run outside the sandbox after the user approves a prompt
excluded.denystring[]Matching commands are never excluded — they always stay inside the sandbox
Example:
{
  "sandbox": {
    "excluded": {
      "allow": ["Exec(git status *)"],
      "ask": ["Exec(git push *)"],
      "deny": ["Exec(git tag *)"]
    }
  }
}
Rule resolution: for each command, the most specific matching rule wins within a source (e.g., Exec(git push *) beats Exec(git *)), and when both user config and team settings match, the more restrictive verdict wins (deny > ask > allow). Commands with no matching rule — including when sandbox.excluded is not configured at all — always run inside the sandbox.
  • Only Exec(...) rules are supported in sandbox.excluded; any other rule type (e.g., Read(...), Write(...)) is ignored with a warning.
  • Exclusion is fail-closed: if a command can’t be safely resolved (e.g., it can’t be parsed), it stays inside the sandbox.
  • Exclusions apply to the default per-command exec path. Commands run through a persistent PTY shell (interactive sessions, or when pty_for_noninteractive_exec is enabled) always stay inside the sandbox.

Enterprise enforcement

Enterprise admins can control sandbox behavior for their entire organization via Team Settings.

Sandbox enforcement mode

Set the enforcement level for the --sandbox flag across your organization:
  • Optional (default) — Users choose whether to pass --sandbox. No enforcement.
  • Required — The --sandbox flag is forced on for all users, even if they don’t pass it on the command line. All CLI sessions run with OS-level file system sandboxing that enforces Read/Write permission scopes.
A future Strict mode may lock down sandbox configuration entirely, preventing users from modifying sandbox settings.
Ensure all target machines are provisioned before setting sandbox enforcement mode to Required across your organization. If any users are on Windows, they will be unable to run the CLI until OS-level sandboxing is supported on Windows or the policy is relaxed to Optional.

Enterprise domain filtering

Admins can also configure organization-wide domain allowlists and denylists:
  • Domain allowlist — When set, only the domains in this list are reachable through the sandbox network proxy. This list is authoritative: it completely replaces any user-configured allowed_domains. Users cannot add additional domains to bypass admin restrictions.
  • Domain denylist — Domains that are always blocked. Enterprise denied domains are additive: they are merged with the user’s local denied_domains, making the combined list more restrictive.
How enterprise and user domain lists interact:
ScenarioEnterprise configUser configEffective result
Admin sets allowlistallowed_domains: ["github.com"]allowed_domains: ["npmjs.org"]Only github.com is allowed (enterprise replaces user list)
Admin sets denylistdenied_domains: ["evil.com"]denied_domains: ["risky.io"]Both evil.com and risky.io are blocked (merged)
No admin allowlistallowed_domains: []allowed_domains: ["github.com"]User’s allowlist is used
Because the user’s local denied_domains are preserved and merged additively, a user could deny a domain that appears in the enterprise allowlist. This is intentional: the combined effect is always more restrictive, never less. If this causes access issues, the user should remove the conflicting entry from their local config.

Enterprise excluded commands

Admins can also set organization-wide excluded command rules in team settings:
  • Excluded allow / askExec(...) rules for commands that may run outside the sandbox across the organization, automatically or after a prompt.
  • Excluded denyExec(...) rules for commands that must never run outside the sandbox. A team deny overrides any user-level allow or ask for matching commands, so users cannot exclude commands their admins have locked down.
Team and user rules are resolved together: the most specific matching rule wins within each source, and the more restrictive verdict wins across sources (deny > ask > allow). Example: lock down all exclusions except gh. A wildcard deny with an allow carve-out keeps every command inside the sandbox except gh, regardless of what users configure locally. These values go into the team-settings excluded-commands configuration (not the user config file, so there is no enclosing sandbox key):
{
  "excluded": {
    "deny": ["Exec(**)"],
    "allow": ["Exec(gh *)"]
  }
}
Because the more specific Exec(gh *) rule beats the wildcard Exec(**), gh commands run outside the sandbox while everything else stays inside — and the team-level wildcard deny overrides any user-level allow or ask rules for other commands.

Further reading