Skip to main content

Security Model

Text the model reads can steer it, so every tool call and command is a request that has to be allowed first. This page shows the pieces, the defaults (governance is on), and how to choose a profile or turn it off.
Every output on this page is what the code printed when it was run. The model’s wording will differ on your run; the policy decisions will not.

The pieces

Every step is recorded in the run’s trace, redacted for privacy. Two independent layers: governance decides (every call passes the policy before it runs) and the sandbox contains (execute commands run in a container, not on your host).

The defaults

Governance is on by default (since 0.5.0), with the permissive-dev profile. What it does with each kind of request:
  • Allowed: the agent’s own tools, its workspace, memory, code mode, skills, sub-agents, background runs, the MCP servers you configured, and commands inside a sandbox.
  • Asked of a person first: leaving a sandbox’s containment, that is, turning the sandbox’s network on (ask_sandbox_network) or mounting host files into it (ask_sandbox_host_mount). Nothing else pauses.
  • Refused without asking: reading raw secrets, host files outside the workspace, network access from the host (any network.* request, rule deny_unrestricted_network_egress), installing packages as a capability (a package.install request, rule deny_unrestricted_package_install), and shell commands on the host.
Inside a sandbox, pip install is not a package.install request: it is an ordinary command, allowed like any other command there. What contains it is the sandbox’s network, which is off until a person approves turning it on. There is no budget until you set one, and no sandbox (no execute tool) until you configure one. governance_config={"enabled": False} turns it off. There is no need to write "enabled": True: written without a profile (or a policy of your own), it selects interactive-dev, as it did before 0.5.0. Every setting is in the agent settings reference.

Choose a profile

Pick a built-in profile (interactive-dev asks a person before network, MCP calls, sub-agents and background runs; strict-production denies what no rule allows), or write your own policy:
Each call is a request for a capability; the trajectory names the rule that decided it, and the header carries the policy’s hash. To run commands in a sandbox too, add a provider:
Install the Docker extra with pip install "omnicoreagent[docker]". Every rule: policy reference. Your own rules: Policies. permissive-dev, the default, allows deletes in the workspace: the agent’s delete_file and clear_files run without asking (its allow_local_dev_workspace rule allows every workspace.* request). The workspace is the agent’s own directory, never files outside it. To have a person approve each delete, add ask rules to the profile:
An ask outranks the profile’s allow, so every other workspace call is still allowed and only these two pause the run (Approvals).

What stops harm

Three layers, each with one job:
  1. The sandbox decides what a command can touch. It is the boundary.
  2. Capability rules decide what the agent’s own tools may do, such as reading a file, an HTTP request, an MCP tool or spawning a worker, where the target is exact.
  3. Command rules decide when to ask about a shell command. They are a convenience, not a boundary (Rules on shell commands).
What each sandbox provider enforces. A manifest asking a provider for anything it does not enforce is refused when the agent is built, so nothing is approved that is not kept: “Checked from inside” means a new sandbox that should have no network tries one outbound connection; if it gets through, the sandbox is destroyed and refused. There are no per-path read or write rules inside a sandbox: a command reaches the sandbox’s own disk and, on Docker, the workspace mount. Which workspace files go in is the workspace bridge’s include and exclude, under the same file rules as read_file.

What the Docker sandbox adds

  • No network unless the policy allows it (the dev profiles ask).
  • Read-only root, unprivileged user, all capabilities dropped, no privilege escalation, a process limit; memory and CPU limits when the manifest’s resources sets them.
  • An in-memory working directory, removed with the container.
  • Only the environment you set; never your credentials.
  • Never mounted, whatever the policy says: the Docker socket, system directories, ~/.ssh, ~/.aws and similar.
  • One container per run, removed when it ends or is cancelled.
For a boundary that does not share your host kernel, install gVisor and set "options": {"runtime": "runsc"} in sandbox_config.

Trust boundaries

Governance decides whether your tool runs, not what it does once it runs.

Built-in protections

  • Sub-agents of a governed agent are governed, under a policy derived from its own.
  • AGENTS.md is guidance only; it cannot grant a permission (AGENTS.md).
  • A policy file the agent could write to is refused (Policies).
  • A policy is hashed when loaded; the hash is on every decision and trace.
  • Sandbox files come back only as governed, bounded copies (no links, hidden, oversized or non-text files).
  • The trace header lists security_warnings, such as ungoverned_host_scripts or sandbox_unused_without_governance (Observability).

What is not protected

  • Anything your policy allows. An allow rule for a dangerous capability is honoured.
  • What a command rule does not name. Command rules match a command’s first words; sudo rm is a command named sudo. The sandbox, not the rule, limits what any command can do.
  • Your own tools and host skill scripts run with your privileges.
  • Data leaving through an allowed channel (an MCP tool, a tool of yours, a sandbox with the network on). There is no data-flow tracking.
  • The host kernel, when the sandbox uses plain Docker rather than gVisor.
  • Governance off. Without it, no policy applies and the sandbox is unused.

When things go wrong

sandbox_config is set but governance was turned off with "enabled": False, so there is no policy and no execute tool. The trace header says so:
Remove "enabled": False: governance is on by default.
The profile name is not one of the three built-in profiles:
Read the call’s governance entries in the trajectory: matched_rule_ids names the rule that decided it, and an empty list with reason_code unknown_capability means no rule matched and the profile’s mode decided. Policies shows how to add a rule.

Next

Policies

Write rules, test that they match, and read each decision.

Approvals

A person in the loop: pause, decide, resume.

Execution

The execute tool, skill scripts and code mode, and what governs each.

Sandbox providers

Docker, E2B, Modal, Daytona, Vercel and more.

Budgets

Put a price on a run, a session or an application.

Guardrails

The injection screen, and what it does and does not catch.

Privacy

What personal data is redacted, and where.

Policy reference

Every capability and every built-in rule.