Policy Reference

Complete policy schema for controlling file, network, command, signal, and registry access.

Policy Model#

Decisions

DecisionDescription
allowPermit the operation
denyBlock the operation
approveRequire human approval
redirectSwap to a different target
auditAllow + log (explicit logging)
soft_deleteQuarantine with restore option

Scopes

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:

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.

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

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

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.

ci-strict.yaml

Safe for CI runners.

agent-sandbox.yaml

"Agent runs unknown code" mode.