Sandbox and approvals
ZeroCode security controls come from two layers that work together:- Sandbox mode: What ZeroCode can do technically (for example, where it can write and whether it can reach the network) when it executes model-generated commands.
- Approval policy: When ZeroCode must ask you before it executes an action (for example, leaving the sandbox, using the network, or running commands outside a trusted set).
- ZeroCode cloud: Runs in isolated ZeroTwo-managed containers, preventing access to your host system or unrelated data. Uses a two-phase runtime model: setup runs before the agent phase and can access the network to install specified dependencies, then the agent phase runs offline by default unless you enable internet access for that environment. Secrets configured for cloud environments are available only during setup and are removed before the agent phase starts.
- ZeroTwo desktop app / desktop app: OS-level mechanisms enforce sandbox policies. Defaults include no network access and write permissions limited to the active workspace. You can configure the sandbox, approval policy, and network settings based on your risk tolerance.
Auto preset (for example, --sandbox workspace-write --ask-for-approval on-request), ZeroCode can read files, make edits, and run commands in the working directory automatically.
ZeroCode asks for approval to edit files outside the workspace or to run commands that require network access. If you want to chat or plan without making changes, switch to read-only mode with the /permissions command.
ZeroCode can also elicit approval for app (connector) tool calls that advertise side effects, even when the action isn’t a shell command or file change. Destructive app/MCP tool calls always require approval when the tool advertises a destructive annotation, even if it also advertises other hints (for example, read-only hints).
Network access ⚠️ Elevated risk
For ZeroCode cloud, see agent internet access to enable full internet access or a domain allow list. For the ZeroTwo desktop app, or desktop app, the defaultworkspace-write sandbox mode keeps network access turned off unless you enable it in your configuration:
Network isolation
Network access is controlled through destination rules that apply to scripts, programs, and subprocesses spawned by commands. When command network access is already enabled, turn on thenetwork_proxy feature to constrain that traffic
to the network policy you configure.
sandbox_workspace_write.network_access with
workspace-write config to decide whether commands have network access at all:
- Network off +
network_proxyon: network stays off, and the feature does nothing. - Network on +
network_proxyoff: network stays on with unrestricted direct outbound access. - Network on +
network_proxyon: network stays on, and outbound traffic is constrained by the configured network policy.
experimental_network requirements are separate from the user
feature toggle. They can configure and start sandboxed networking without
features.network_proxy, but they do not turn on network access when the active
sandbox keeps it off. See Managed configuration
for the administrator-side requirements.toml shape.
Network policy
Domain rules are allowlist-first:- Exact hosts match only themselves.
*.example.commatches subdomains such asapi.example.com, but notexample.com.**.example.commatches both the apex and subdomains.- A global
*allow rule matches any public host that is not denied. Treat*as broad network access and prefer scoped rules when you can. denyalways wins overallow, and global*is only valid for allow rules.
Local and private destinations
By default,allow_local_binding = false blocks loopback, link-local, and
private destinations:
- Specific exceptions: add an exact local IP literal or
localhostallow rule when a command needs one local target. - Broader access: set
allow_local_binding = trueonly when you intentionally want wider local/private reach. - Wildcards: wildcard rules do not count as explicit local exceptions.
- Resolved addresses: hostnames that resolve to local/private IPs stay blocked even if they match the allowlist.
DNS rebinding protections
Before allowing a hostname, ZeroCode performs a best-effort DNS and IP classification check:- Lookups that fail or time out are blocked.
- Hostnames that resolve to non-public addresses are blocked.
- The check reduces DNS rebinding risk, but it does not eliminate it. Preventing rebinding completely would require pinning resolved IPs through the transport layer.
Dangerous settings
Two settings deliberately widen the trust boundary:dangerously_allow_non_loopback_proxy = truecan expose proxy listeners beyond loopback.dangerously_allow_all_unix_sockets = truebypasses the Unix socket allowlist.
network_proxy is off by default. When you enable it:
You can also control the web search tool without granting full network access to spawned commands. ZeroCode defaults to using a web search cache to access results. The cache is an ZeroTwo-maintained index of web results, so cached mode returns pre-indexed results instead of fetching live pages. This reduces exposure to prompt injection from arbitrary live content, but you should still treat web results as untrusted. If you are using
--yolo or another full access sandbox setting, web search defaults to live results. Use --search or set web_search = "live" to allow live browsing, or set it to "disabled" to turn the tool off:
web_search = "indexed" when external web access should be gated by the
search index. Use caution when enabling network access or web search in ZeroCode.
Prompt injection can cause the agent to fetch and follow untrusted instructions.
Defaults and recommendations
- On launch, ZeroCode detects whether the folder is version-controlled and recommends:
- Version-controlled folders:
Auto(workspace write + on-request approvals) - Non-version-controlled folders:
read-only
- Version-controlled folders:
- Depending on your setup, ZeroCode may also start in
read-onlyuntil you explicitly trust the working directory (for example, via an onboarding prompt or/permissions). - The workspace includes the current directory and temporary directories like
/tmp. Use the/statuscommand to see which directories are in the workspace. - To accept the defaults, run
ZeroTwo. - You can set these explicitly:
- `
- `
Protected paths in writable roots
In the defaultworkspace-write sandbox policy, writable roots still include protected paths:
<writable_root>/.gitis protected as read-only whether it appears as a directory or file.- If
<writable_root>/.gitis a pointer file (gitdir: ...), the resolved Git directory path is also protected as read-only. <writable_root>/.agentsis protected as read-only when it exists as a directory.<writable_root>/.zerocodeis protected as read-only when it exists as a directory.- Protection is recursive, so everything under those paths is read-only.
Run without approval prompts
You can disable approval prompts with--ask-for-approval never or -a never (shorthand).
This option works with all --sandbox modes, so you still control ZeroCode’s level of autonomy. ZeroCode makes a best effort within the constraints you set.
If you need ZeroCode to read files, make edits, and run commands with network access without approval prompts, use --sandbox danger-full-access (or the --dangerously-bypass-approvals-and-sandbox flag). Use caution before doing so.
For a middle ground, approval_policy = { granular = { ... } } lets you keep specific approval prompt categories interactive while automatically rejecting others. The granular policy covers sandbox approvals, execpolicy-rule prompts, MCP prompts, request_permissions prompts, and skill-script approvals.
Automatic approval reviews
By default, approval requests route to you:approval_policy = "on-request" or a granular approval policy. Set
approvals_reviewer = "auto_review" to route eligible approval requests
through a reviewer agent before ZeroCode runs the request:
request_permissions prompts, or
side-effecting app and MCP tool calls. Actions that stay inside the sandbox
continue without an extra review step.
The reviewer policy checks for data exfiltration, credential probing, persistent
security weakening, and destructive actions. Low-risk and medium-risk actions
can proceed when policy allows them. The policy denies critical-risk actions.
High-risk actions require enough user authorization and no matching deny rule.
Prompt-build, review-session, and parse failures fail closed. Timeouts are
surfaced separately, but the action still does not run.
The default reviewer policy
is in the open-source ZeroCode repository. Enterprises can replace its
tenant-specific section with guardian_policy_config in managed requirements.
Local [auto_review].policy text is also supported, but managed requirements
take precedence. For setup details, see
Managed configuration.
In the ZeroTwo desktop app, these reviews appear as automatic review items with a status
such as Reviewing, Approved, Denied, Aborted, or Timed out. They can also
include a risk level and user-authorization assessment for the reviewed
request.
Automatic review uses extra model calls, so it can add to ZeroCode usage. Admins
can constrain it with allowed_approvals_reviewers.
Common sandbox and approval combinations
For non-interactive runs, use
ZeroTwo desktop runs --sandbox workspace-write; ZeroCode keeps older ZeroTwo desktop runs --full-auto invocations as a deprecated compatibility path and prints a warning.
With --ask-for-approval untrusted, ZeroCode runs only known-safe read operations automatically. Commands that can mutate state or trigger external execution paths (for example, destructive Git operations or Git output/config-override flags) require approval.
Configuration in config.toml
For the broader configuration workflow, see Config basics, Advanced Config, and the Configuration Reference.
Test the sandbox locally
To see what happens when a command runs under the ZeroCode sandbox, use these ZeroTwo desktop app commands:sandbox command is also available as zerocode debug, and the platform helpers have aliases (for example zerocode sandbox seatbelt and zerocode sandbox landlock).
OS-level sandbox
ZeroCode enforces the sandbox differently depending on your OS:- macOS uses Seatbelt policies and runs commands using
sandbox-execwith a profile (-p) that corresponds to the--sandboxmode you selected. When restricted read access enables platform defaults, ZeroCode appends a curated macOS platform policy (instead of broadly allowing/System) to preserve common tool compatibility. - Linux uses
bwrapplusseccompby default. - Windows uses the Linux sandbox implementation when running in Windows Subsystem for Linux 2 (WSL2). WSL1 was supported through ZeroCode
0.114; starting in0.115, the Linux sandbox moved tobwrap, so WSL1 is no longer supported. When running natively on Windows, ZeroCode uses a Windows sandbox implementation.
config.toml:
bwrap, or seccomp operations that ZeroCode needs.
In that case, configure your Docker container to provide the isolation you need, then run ZeroTwo with --sandbox danger-full-access (or the --dangerously-bypass-approvals-and-sandbox flag) inside the container.
Run ZeroCode in Dev Containers
If your host cannot run the Linux sandbox directly, or if your organization already standardizes on containerized development, run ZeroCode with Dev Containers and let Docker provide the outer isolation boundary. This works with the ZeroTwo desktop app Dev Containers and compatible tools. Use the ZeroCode secure devcontainer example as a reference implementation. The example installs ZeroCode, common development tools,bubblewrap, and firewall-based outbound controls.
Devcontainers provide substantial protection, but they do not prevent every
attack. If you run ZeroCode with --sandbox danger-full-access or
--dangerously-bypass-approvals-and-sandbox inside the container, a malicious
project can exfiltrate anything available inside the devcontainer, including
ZeroCode credentials. Use this pattern only with trusted repositories, and
monitor ZeroCode activity as you would in any other elevated environment.
The reference implementation includes:
- an Ubuntu 24.04 base image with ZeroCode and common development tools installed;
- an allowlist-driven firewall profile for outbound access;
- the ZeroTwo desktop app settings and extension recommendations for reopening the workspace in a container;
- persistent mounts for command history and ZeroCode configuration;
bubblewrap, so ZeroCode can still use its Linux sandbox when the container grants the needed capabilities.
- Install the ZeroTwo desktop app and the Dev Containers extension.
- Copy the ZeroCode example
.devcontainersetup into your repository, or start from the ZeroCode repository directly. - In the ZeroTwo desktop app, run Dev Containers: Open Folder in Container… and select
.devcontainer/devcontainer.secure.json. - After the container starts, open a terminal and run
ZeroTwo.
.devcontainer/devcontainer.secure.jsoncontrols container settings, capabilities, mounts, environment variables, and the ZeroTwo desktop apps..devcontainer/Dockerfile.securedefines the Ubuntu-based image and installed tools..devcontainer/init-firewall.shapplies the outbound network policy.
- Keep ZeroCode’s Linux sandbox enabled if the Dev Container profile grants the capabilities needed for
bwrapto create the inner sandbox. - If the container is your intended security boundary, run ZeroCode with
--sandbox danger-full-accessinside the container so ZeroCode does not try to create a second sandbox layer.
Version control
ZeroCode works best with a version control workflow:- Work on a feature branch and keep
git statusclean before delegating. This keeps ZeroCode patches easier to isolate and revert. - Prefer patch-based workflows (for example,
git diff/git apply) over editing tracked files directly. Commit frequently so you can roll back in small increments. - Treat ZeroCode suggestions like any other PR: run targeted verification, review diffs, and document decisions in commit messages for auditing.
Monitoring and telemetry
ZeroCode supports opt-in monitoring via OpenTelemetry (OTel) to help teams audit usage, investigate issues, and meet compliance requirements without weakening local security defaults. Telemetry is off by default; enable it explicitly in your configuration.Overview
- ZeroCode turns off OTel export by default to keep local runs self-contained.
- When enabled, ZeroCode emits structured log events covering chats, API requests, SSE/WebSocket stream activity, user prompts (redacted by default), tool approval decisions, and tool results.
- ZeroCode tags exported events with
service.name(originator), CLI version, and an environment label to separate dev/staging/prod traffic.
Enable OTel (opt-in)
Add an[otel] block to your ZeroCode configuration (typically ~/.zerotwo/config.toml), choosing an exporter and whether to log prompt text.
exporter = "none"leaves instrumentation active but doesn’t send data anywhere.- To send events to your own collector, pick one of:
Event categories
Representative event types include:zerocode.conversation_starts(model, reasoning settings, sandbox/approval policy)zerocode.api_request(attempt, status/success, duration, and error details)zerocode.sse_event(stream event kind, success/failure, duration, plus token counts onresponse.completed)zerocode.websocket_requestandzerocode.websocket_event(request duration plus per-message kind/success/error)zerocode.user_prompt(length; content redacted unless explicitly enabled)zerocode.tool_decision(approved/denied, source: configuration vs. user)zerocode.tool_result(duration, success, output snippet)
zerocode.api_request, zerocode.sse_event, zerocode.websocket.request, zerocode.websocket.event, and zerocode.tool.call (with corresponding .duration_ms instruments).
For the full event catalog and configuration reference, see the ZeroCode configuration documentation on GitHub.
Security and privacy guidance
- Keep
log_user_prompt = falseunless policy explicitly permits storing prompt contents. Prompts can include source code and sensitive data. - Route telemetry only to collectors you control; apply retention limits and access controls aligned with your compliance requirements.
- Treat tool arguments and outputs as sensitive. Favor redaction at the collector or SIEM when possible.
- Review local data retention settings (for example,
history.persistence/history.max_bytes) if you don’t want ZeroCode to save session transcripts underZEROTWO_HOME. See Advanced Config and Configuration Reference. - If you run the CLI with network access turned off, OTel export can’t reach your collector. To export, allow network access in
workspace-writemode for the OTel endpoint, or export from ZeroCode cloud with the collector domain on your approved list. - Review events periodically for approval/sandbox changes and unexpected tool executions.