Policy Reference
Complete policy schema for controlling file, network, command, signal, and registry access.
Policy Model#
Decisions
| Decision | Description |
|---|---|
allow | Permit the operation |
deny | Block the operation |
approve | Require human approval |
redirect | Swap to a different target |
audit | Allow + log (explicit logging) |
soft_delete | Quarantine with restore option |
Scopes
- File operations
- Commands
- Environment variables
- Network (DNS/connect)
- PTY/session settings
- Signals (Linux only for blocking)
- Registry (Windows only)
Evaluation
First matching rule wins. Rules live in a named policy; sessions choose a policy at creation time.
File Rules#
Control file system operations by path and operation type.
file_rules:
# Allow reading workspace
- name: allow-workspace-read
paths:
- "/workspace"
- "/workspace/**"
operations: [read, open, stat, list, readlink]
decision: allow
# Require approval for deletes
- name: approve-workspace-delete
paths: ["/workspace/**"]
operations: [delete, rmdir]
decision: approve
message: "Agent wants to delete: {{.Path}}"
timeout: 5m
# Block sensitive paths
- name: deny-ssh-keys
paths: ["/home/**/.ssh/**", "/root/.ssh/**"]
operations: ["*"]
decision: deny
Operations: read, open, stat, list, readlink, write, create, mkdir, chmod, rename, delete, rmdir, * (all)
Network Rules#
Control network connections by domain, CIDR, or port.
network_rules:
# Allow package registries
- name: allow-npm
domains: ["registry.npmjs.org", "*.npmjs.org"]
ports: [443, 80]
decision: allow
# Block private networks
- name: block-private
cidrs:
- "10.0.0.0/8"
- "172.16.0.0/12"
- "192.168.0.0/16"
decision: deny
# Block cloud metadata
- name: block-metadata
cidrs: ["169.254.169.254/32"]
decision: deny
# Approve unknown HTTPS
- name: approve-unknown
ports: [443]
decision: approve
message: "Connect to {{.RemoteAddr}}:{{.RemotePort}}?"
Command Rules#
Pre-execution checks for commands. With execve interception enabled (Linux full mode), rules also apply to nested commands spawned by scripts.
command_rules:
# Safe commands
- name: allow-safe
commands: [ls, cat, grep, find, pwd, echo, git, node, python]
decision: allow
# Approve package installs
- name: approve-install
commands: [npm, pip, cargo]
args_patterns: ["install*", "add*"]
decision: approve
message: "Install packages: {{.Args}}"
# Block dangerous patterns
- name: block-rm-rf
commands: [rm]
args_patterns: ["*-rf*", "*-fr*"]
decision: deny
# Block system commands
- name: block-system
commands: [shutdown, reboot, systemctl, mount, dd, kill]
decision: deny
Signal Rules#
Control which processes can send signals to which targets. Full blocking only on Linux; macOS and Windows provide audit only.
signal_rules:
# Allow signals to self and children
- name: allow-self
signals: ["@all"]
target:
type: self
decision: allow
# Redirect SIGKILL to graceful SIGTERM
- name: graceful-kill
signals: ["SIGKILL"]
target:
type: children
decision: redirect
redirect_to: SIGTERM
# Block fatal signals to external processes
- name: deny-external-fatal
signals: ["@fatal"]
target:
type: external
decision: deny
# Silently absorb job control signals from external sources
- name: absorb-external-job
signals: ["@job"]
target:
type: external
decision: absorb
Signal groups:
@all- All signals (1-31)@fatal- SIGKILL, SIGTERM, SIGQUIT, SIGABRT@job- SIGSTOP, SIGCONT, SIGTSTP, SIGTTIN, SIGTTOU@reload- SIGHUP, SIGUSR1, SIGUSR2
Target types: self, children, descendants, session, external, system
Signal decisions: allow, deny, audit, approve, redirect (to another signal), absorb (discard silently)
Registry Rules (Windows)#
Control Windows registry access. Requires mini filter driver.
registry_rules:
# Block persistence locations
- name: block-run-keys
paths:
- 'HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*'
- 'HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run*'
operations: [write, create, delete]
decision: deny
# Block security settings
- name: block-defender
paths: ['HKLM\SOFTWARE\Policies\Microsoft\Windows Defender*']
operations: [write, create, delete]
decision: deny
# Allow reads everywhere
- name: allow-read
paths: ["*"]
operations: [read]
decision: allow
Resource Limits#
Constrain resource usage per session. Full enforcement on Linux only.
resource_limits:
# Memory
max_memory_mb: 2048
memory_swap_max_mb: 0
# CPU
cpu_quota_percent: 80
# Disk I/O
disk_read_bps_max: 104857600 # 100 MB/s
disk_write_bps_max: 52428800 # 50 MB/s
# Network
net_bandwidth_mbps: 100
# Process limits
pids_max: 100
# Time limits
command_timeout: 5m
session_timeout: 4h
idle_timeout: 30m
MCP Rules#
The mcp_rules section in a policy file defines MCP security enforcement. This is the policy-file equivalent of the sandbox.mcp runtime configuration.
mcp_rules:
enforce_policy: true
# Server-level access control
server_policy: "allowlist"
allowed_servers:
- id: "trusted_*"
denied_servers:
- id: "untrusted_*"
# Tool-level access control
tool_policy: "allowlist"
allowed_tools:
- server: "database"
tool: "query_users"
content_hash: "sha256:abc123..."
- server: "notes"
tool: "read_*"
denied_tools:
- server: "*"
tool: "exec_*"
# Version pinning
version_pinning:
enabled: true
on_change: "block"
auto_trust_first: true
# Cross-server attack detection
cross_server:
enabled: true
read_then_send:
enabled: true
burst:
enabled: true
See the MCP Policy Configuration section for detailed descriptions of each option.
Environment Policy#
Control which environment variables processes can access.
- Defaults: With no
env_allow, agentsh builds a minimal env (PATH/LANG/TERM/HOME) and strips built-in secret keys - Overrides: Per-command
env_allow/env_denyplus limits - Block iteration:
env_block_iteration: truehides env enumeration
Global policy (applies to all commands)
env_policy:
# Allowlist - only these vars are visible (supports wildcards)
allow:
- "PATH"
- "HOME"
- "LANG"
- "TERM"
- "NODE_*" # All NODE_ prefixed vars
- "npm_*"
# Denylist - these are always stripped (even if in allow)
deny:
- "AWS_*"
- "GITHUB_TOKEN"
- "*_SECRET*"
- "*_KEY"
- "*_PASSWORD"
# Size limits
max_bytes: 1000000 # Max total env size
max_keys: 100 # Max number of variables
# Block enumeration (env, printenv, /proc/*/environ)
block_iteration: true
Per-command overrides
Override the global policy for specific commands:
command_rules:
# npm needs registry tokens
- name: npm-with-tokens
commands: [npm]
decision: allow
env_allow:
- "NPM_TOKEN"
- "NODE_AUTH_TOKEN"
env_deny:
- "AWS_*" # Still deny cloud creds
# Build tools get more env access
- name: build-tools
commands: [make, cargo, go]
decision: allow
env_allow:
- "CC"
- "CXX"
- "GOPATH"
- "CARGO_*"
env_max_bytes: 500000
env_max_keys: 50
# Prevent scripts from discovering env vars
- name: untrusted-scripts
commands: [python, node, ruby]
args_patterns: [".*\\.sh$", ".*eval.*"]
decision: allow
env_block_iteration: true
Environment Injection#
Inject operator-trusted environment variables into every command execution, regardless of the parent environment. Injected variables bypass env_policy filtering since they are configured by the operator.
Use cases
- Shell builtin hardening: Set
BASH_ENVto disable bash builtins that bypass seccomp policy (likekill,ulimit) - Runtime injection: Add variables for environments that strip Docker ENV (e.g., Blaxel)
- Operator defaults: Configure variables that should always be present
Global configuration
Set in your config.yml to apply to all executions:
sandbox:
env_inject:
BASH_ENV: "/usr/lib/agentsh/bash_startup.sh"
# Add custom variables as needed
MY_CUSTOM_VAR: "value"
Policy-level configuration
Override or extend global settings in a policy file:
version: 1
name: my-policy
env_inject:
BASH_ENV: "/etc/mycompany/bash_startup.sh"
EXTRA_VAR: "policy-specific"
# ... rest of policy
Merge behavior
- Start with global
sandbox.env_inject - Layer policy
env_injecton top - Policy wins on key conflicts
- Result bypasses
env_policyfiltering (operator-trusted)
Bundled bash startup script
agentsh includes a script at /usr/lib/agentsh/bash_startup.sh that disables bash builtins which could bypass seccomp policy enforcement:
#!/bin/bash
# Disable builtins that bypass seccomp policy enforcement
enable -n kill # Signal sending
enable -n enable # Prevent re-enabling
enable -n ulimit # Resource limits
enable -n umask # File permission mask
enable -n builtin # Force builtin bypass
enable -n command # Function/alias bypass
This script is included in Linux packages (deb, rpm, arch, tarballs). Set BASH_ENV to this path to automatically disable these builtins in bash sessions.
Starter Policy Packs#
Pre-built policies for common scenarios:
dev-safe.yaml
Safe for local development.
- Allow workspace read/write
- Approve deletes in workspace
- Deny
~/.ssh/**,/root/.ssh/** - Restrict network to allowlisted domains
ci-strict.yaml
Safe for CI runners.
- Deny anything outside workspace
- Deny outbound network except artifact registries
- Deny interactive shells
- Audit everything
agent-sandbox.yaml
"Agent runs unknown code" mode.
- Default deny + explicit allowlist
- Approve any credential/path access
- Redirect network tools to internal proxies
- Soft-delete destructive operations