Two different sandboxes. Comis has two distinct sandbox concepts that are
sometimes conflated:
- Skill sandbox (this page) — application-level protection that runs whenever a skill is loaded or invoked: content scanning, sanitization, tool policy, budget caps. This applies to all skills regardless of how they execute.
- Exec sandbox (separate page) — OS-level
filesystem isolation for the
system.exectool only, using bubblewrap on Linux or sandbox-exec on macOS. It does not sandbox arbitrary agent code, MCP servers, or in-process Node tools.
What the Sandbox Protects Against
The sandboxing system is designed to catch a range of threats:- Malicious skills — A skill that tries to execute system commands, read environment variables, or exfiltrate data
- Compromised dependencies — An MCP server or external tool that has been tampered with
- Resource abuse — A skill that consumes excessive memory, CPU, or network bandwidth
- Data exfiltration — A skill that tries to send your data to external servers
- Prompt injection via skills — A skill that contains hidden instructions to override agent behavior
How the Sandbox Works
The sandboxing process is automatic. When an agent loads a skill, Comis runs it through a pipeline of checks before the skill can execute. You do not need to invoke the sandbox manually — it is always active for all skills. The key principle is defense in depth: each layer catches a different type of threat, so a skill must pass all of them to execute. A threat that slips past one layer is caught by the next.The Four Layers of Sandboxing
Skills pass through four layers of protection before and during execution. Each layer catches a different category of threat.1
Content Scanning
Before a skill is loaded, Comis scans its content for six threat categories:
- Command execution — Shell commands, eval calls, subprocess invocations
- Environment harvesting — Attempts to read API keys from environment variables
- Cryptocurrency mining — Crypto mining scripts or wallet addresses
- Network exfiltration — Suspicious outbound network requests
- Obfuscated encoding — Base64-encoded payloads and other encoding tricks
- XML injection — XML entity attacks and breakout attempts
2
Sanitization
All skill content passes through a four-step sanitization pipeline:
- HTML comment stripping — Removes hidden instructions embedded in HTML comments
- Unicode normalization (NFKC) — Converts visually similar characters to their canonical forms
- Invisible character removal — Strips zero-width characters and other invisible Unicode
- Size enforcement — Rejects content exceeding the 20,000 character limit
3
Tool Policy
Each agent has a tool policy that controls which tools skills can access. Five built-in profiles give you a starting point:
- minimal — Basic file operations only
- coding — Development tools (read, write, edit, execute)
- messaging — Communication tools only
- supervisor — Fleet management and administration
- full — All tools, no restrictions (this is the default)
4
Execution Constraints
During execution, additional safety limits apply:
- Budget caps prevent runaway API costs by limiting tokens per execution
- Circuit breakers pause agents with high error rates to prevent cascading failures
- Step limits cap the number of tool calls per execution
OS-Level Filesystem Sandbox (Exec Tool)
For the special case of thesystem.exec tool, which spawns a shell, the
skill-level layers above are reinforced by a kernel-enforced filesystem
namespace. This is the only Comis sandbox that operates at the OS level.
The provider is auto-detected at daemon startup — Comis picks bwrap on
Linux and sandbox-exec on macOS. If the binary is missing, the exec tool
logs a warning and falls back to running unsandboxed (you can change this to
hard-fail by setting
execSandbox.enabled: "always" and ensuring the binary
is installed).
Successful exec call vs blocked exec call
Here is what an agent sees when it tries to read a permitted vs forbidden path through the exec tool. The agent’s workspace lives at~/.comis/workspace-code-assistant/.
Autonomy jail hardening
When an agent runs an autonomy-bearing surface (the orchestrate/script runner), the bwrap jail is hardened beyond the baseline filesystem isolation. These controls are defense-in-depth — each one stands alone if another is absent:- Process hardening —
--new-session(a fresh session keyring + no controlling TTY, which neutralizes the TIOCSTI keystroke-injection escape) and--die-with-parent(the jail dies with the daemon, no orphaned escape). - Seccomp profile — an optional
--seccompBPF filter denies the dangerous syscall surface (keyring,ptrace,perf_event_open,bpf, module loading) while allowing what interpreters need. The filter is a precompiled blob generated offline; when it is absent the jail degrades gracefully (the other controls still apply) rather than failing to start. - Bind-mount validator — every dynamic, caller- or agent-supplied bind
(workspace, temp dir, shared paths, read-only discovery paths) is screened
against a denylist backstop before it is mounted. A bind that resolves into a
system dir (
/etc,/proc,/sys,/dev,/root,/run) or a credential dir (~/.ssh,~/.aws,~/.gnupg,~/.config,~/.npm,~/.netrc) — or a symlink whose real target does — is refused at jail construction (it fails loud; it is never silently mounted). Symlinks are resolved through every ancestor, so a symlinked leaf cannot smuggle a blocked path past a naive string check. - Writable-path audit — no host-trusted writable path (the agent config,
hooks, cron jobs,
~/.nvm, learned-memory/skill files, or the bound Node binary) is mounted read-write, and no read-only mount of a parent lets a not-yet-existing child config be created inside the jail. - Namespace preflight — at startup Comis probes whether the host can build an unprivileged user namespace. If it cannot, the autonomy posture downshifts to assistant with a loud doctor/boot signal and a remediation hint — it never silently falls back to an unjailed run.
- Node-runtime honesty — surfaces that need
nodeinside the jail probe for it on the jail PATH; if absent, the daemon’s ownnodebinary is bound read-only; if neither works, those surfaces are reported unavailable with a loud signal. Comis never claims a “bundled Node” and never silently runs them unjailed.
What Happens When a Threat Is Found
The response depends on the severity of the finding:- Critical threat — The skill is blocked from loading. An audit event is recorded. The agent continues without the compromised skill.
- Warning — The skill loads with a warning logged. The audit trail records the concern for your review.
- Clean — The skill passes all checks and loads normally.
If a legitimate skill is incorrectly flagged as a threat, you can adjust the content scanning configuration to allow specific patterns. See Security Scanning for details.
Configuration
The most relevant sandbox settings are shown below. Detailed configuration lives on the linked pages.~/.comis/config.yaml
Sandbox no-downgrade invariant
A confined agent must not be able to escalate by delegation — spawning a sub-agent that runs with a less confined sandbox than itself. Comis enforces a fail-closed no-downgrade invariant on the sub-agent spawn path: a child spawn is refused before any run or session is created when the child’s resolved sandbox posture would be less confined than its spawner’s on any dimension (exec / filesystem / network / uid), and asecurity:sandbox_downgrade_refused event is emitted. Missing posture config folds to the most-confined value, so a posture is never inferred more permissive than reality. For sub-agents today the exec sandbox dimension is the active one; the other dimensions are reserved for the deferred terminal path. The invariant is on by default and controlled by security.agentToAgent.sandboxNoDowngrade; see the Threat Model for the trust-boundary rationale.
MCP Server Sandboxing
MCP (Model Context Protocol) integrations connect your agents to external tools and data sources. Because MCP servers run as separate processes, they receive the same sandboxing treatment as other skills:- Content scanning applies to the MCP server manifest and tool descriptions
- Tool policy controls which MCP tools your agents can use
- Execution constraints apply to MCP tool calls just like built-in tool calls
Related
Security Scanning
Detailed content scanner documentation
Tool Policy
Configure per-agent tool restrictions
Defense in Depth
How sandboxing fits into the security layers
Sandbox Reference
Technical sandbox reference
