agentsh Documentation
Secure, policy-enforced execution gateway for AI agents. Intercept file, network, and process activity at runtime with full audit logs.
What is agentsh#
agentsh sits under your agent/tooling—intercepting file, network, process, and signal activity (including subprocess trees), enforcing the policy you define, and emitting structured audit events.
Drop-in Shell
Turns every command (and its subprocesses) into auditable events.
Policy Engine
Per-operation decisions: allow, deny, approve, redirect, or soft_delete.
Full Visibility
File I/O, network, DNS, process lifecycle, PTY activity, and LLM requests.
Two Output Modes
Human-friendly shell output or compact JSON for agents/tools.
Redirect & Steer
Swap commands or file paths to keep agents on the paved road.
LLM Proxy & DLP
Intercept API requests, redact PII, and track token usage.
Checkpoints
Snapshot workspace state and rollback destructive operations.
Cross-Platform
Linux, macOS, and Windows with native enforcement mechanisms.
Why agentsh?
Agent workflows eventually run arbitrary code (pip install, make test, python script.py). Traditional "ask for approval before running a command" controls stop at the tool boundary and can't see what happens inside that command.
agentsh enforces policy at runtime, so hidden work done by subprocesses is still governed, logged, and (when required) approved.
Quick Start#
The fastest way to understand agentsh is to run something that spawns subprocesses and touches the filesystem/network.
# 1) Create a session in your repo/workspace
SID=$(agentsh session create --workspace . | jq -r .id)
# 2) Run something simple (human-friendly output)
agentsh exec "$SID" -- uname -a
# 3) Run something that hits the network (JSON output + event summary)
agentsh exec --output json --events summary "$SID" -- curl -s https://example.com
# 4) Trigger a policy decision - try to delete something
agentsh exec "$SID" -- rm -rf ./tmp
# 5) See what happened (structured audit trail)
agentsh exec --output json --events full "$SID" -- ls
What you'll see in the JSON output:
exit_code: the command's exit statusstdout/stderr: captured outputevents[]: every file/network/process operation with policy decisionspolicy.decision:allow,deny,approve, orredirect
Installation#
From a GitHub Release
Download the .deb, .rpm, or .apk for your platform from the releases page.
# Example for Debian/Ubuntu
sudo dpkg -i agentsh_<VERSION>_linux_amd64.deb
From Source (Linux)
make build
sudo install -m 0755 bin/agentsh bin/agentsh-shell-shim /usr/local/bin
From Source (macOS)
# FUSE-T mode (standard, requires brew install fuse-t)
CGO_ENABLED=1 go build -o bin/agentsh ./cmd/agentsh
# ESF+NE enterprise mode (requires Xcode 15+, Apple entitlements)
make build-macos-enterprise
Platform Support#
agentsh supports Linux, macOS, and Windows with varying levels of enforcement capability.
Linux#
100% Score Full enforcement with all features.
Linux provides the most complete security coverage:
- File interception: FUSE3 with blocking and policy enforcement
- Network: iptables with full TCP/UDP/DNS interception
- Process isolation: Full namespace isolation (mount, net, PID, user)
- Syscall filtering: seccomp-bpf with allowlists
- Signal interception: Full blocking and redirect via seccomp
- Resource limits: cgroups v2 for CPU, memory, disk I/O, network
Root or CAP_SYS_ADMIN for namespaces. eBPF requires kernel 5.x+ for full features.
macOS#
macOS supports three deployment options:
ESF+NE (Enterprise) 90%
Best for commercial security products. Uses Endpoint Security Framework for file monitoring and Network Extension for traffic interception.
- ESF requires Apple approval (business justification needed)
- Network Extension is standard capability since Nov 2016
- No namespace isolation (macOS limitation)
- Signal interception: audit only
FUSE-T (Standard) 70%
Easy setup for development and personal use. Install via brew install fuse-t.
- File interception via FUSE-T (NFS protocol)
- Network via pf packet filter (requires root)
- Minimal isolation via sandbox-exec
- No syscall filtering
Lima VM 85%
Full isolation via Linux VM. Best for production on macOS when you need full security features.
- Full Linux features inside VM
- ~200-500MB RAM overhead
- Slightly slower file I/O through virtiofs
Windows#
Native 85%
Uses mini filter driver with AppContainer sandbox isolation.
- File/registry interception via kernel-mode mini filter
- Network via WinDivert (requires admin)
- Registry monitoring and blocking
- AppContainer for process isolation
- Signal interception: audit only via ETW
WSL2 100%
Full Linux features in Windows Subsystem for Linux.
- Same capabilities as native Linux
- No Windows registry monitoring
- Slight VM overhead
Platform Comparison#
| Feature | Linux | macOS ESF | macOS FUSE-T | Windows |
|---|---|---|---|---|
| File blocking | Yes | Yes | Yes | Yes |
| Network blocking | Yes | Yes | Yes | Yes |
| Signal blocking | Yes | Audit | Audit | Audit |
| Namespace isolation | Full | None | None | Partial |
| Syscall filtering | Yes | Exec only | No | No |
| Resource limits | Full | None | None | Partial |
On hosted sandbox platforms (Sprites, Modal, E2B, etc.), some Linux features like namespace isolation, syscall filtering, and resource limits may be unavailable or restricted due to the underlying kernel configuration. File and network blocking typically work, but verify feature availability for your specific platform.
Running Inside Containers#
Containers isolate the host surface; agentsh adds in-container runtime visibility and policy.
- Per-operation audit (files, network, commands) shows what happened during installs/builds/tests
- Approvals and rules persist across long-lived shells and subprocess trees
- Path-level controls on mounted workspaces/caches/creds
- Same behavior on host and in containers—CI and local dev see the same policy outcomes
- Daytona integration — agentsh in Daytona dev environments
- E2B integration — agentsh in E2B sandboxes
- Runloop integration — agentsh in Runloop sandboxes
Shell Shim
The shell shim replaces /bin/sh and /bin/bash so that any shell invocation routes through agentsh—including subprocess calls from scripts, package managers, and build tools.
agentsh shim install-shell \
--root / \
--shim /usr/bin/agentsh-shell-shim \
--bash \
--i-understand-this-modifies-the-host
Point the shim at your server:
ENV AGENTSH_SERVER=http://127.0.0.1:18080
Now any /bin/sh -c ... or /bin/bash -lc ... in the container routes through agentsh.
Docker Setup
Example Dockerfile (Debian-based):
FROM debian:bookworm-slim
ARG AGENTSH_REPO=canyonroad/agentsh
ARG AGENTSH_TAG=v0.1.0
ARG DEB_ARCH=amd64
RUN set -eux; \
apt-get update; \
apt-get install -y --no-install-recommends ca-certificates curl bash; \
rm -rf /var/lib/apt/lists/*
RUN set -eux; \
version="${AGENTSH_TAG#v}"; \
deb="agentsh_${version}_linux_${DEB_ARCH}.deb"; \
url="https://github.com/${AGENTSH_REPO}/releases/download/${AGENTSH_TAG}/${deb}"; \
curl -fsSL -L "${url}" -o /tmp/agentsh.deb; \
dpkg -i /tmp/agentsh.deb; \
rm -f /tmp/agentsh.deb; \
agentsh shim install-shell \
--root / \
--shim /usr/bin/agentsh-shell-shim \
--bash \
--i-understand-this-modifies-the-host
CMD ["/bin/sh", "-lc", "echo hello from agentsh shim"]
Sidecar Pattern
Recommended: Run agentsh as a sidecar (or PID 1) in the same pod/service and share a workspace volume. The shim ensures every shell hop stays under policy.
# docker-compose.yml
services:
agentsh:
image: agentsh:latest
volumes:
- workspace:/workspace
ports:
- "18080:18080"
agent:
image: your-agent:latest
environment:
- AGENTSH_SERVER=http://agentsh:18080
volumes:
- workspace:/workspace
depends_on:
- agentsh
volumes:
workspace:
Local Development#
For local development outside containers:
# Start the server (optional if using autostart)
./bin/agentsh server --config configs/server-config.yaml
# Create a session and run a command
SID=$(./bin/agentsh session create --workspace . | jq -r .id)
./bin/agentsh exec "$SID" -- ls -la
# Structured output for agents
./bin/agentsh exec --output json --events summary "$SID" -- curl https://example.com
You don't need to start agentsh server manually. The first agentsh exec automatically launches a local server using the config file. Set AGENTSH_NO_AUTO=1 to manage the server lifecycle yourself.
Protecting Dev Tools
AI coding assistants like Claude Code, Cursor, and Codex don't just run the commands you see—they also make internal implementation decisions, run subprocesses, and access files without explicit tool calls. Running the dev tool itself through agentsh gives you visibility and policy enforcement over all activity, not just the commands shown in the UI.
When an AI assistant decides to "check something quickly" or "read a file for context," those operations happen silently. Without agentsh wrapping the entire process, you only see what the tool chooses to show you.
Wrapping your dev tool
Instead of running your AI assistant directly, launch it through agentsh:
# Create a session for your workspace
SID=$(agentsh session create --workspace . | jq -r .id)
# Run Claude Code through agentsh
agentsh exec "$SID" -- claude
# Or run Cursor through agentsh
agentsh exec "$SID" -- cursor .
# Or any other dev tool
agentsh exec "$SID" -- code .
What you gain
- Full audit trail: Every file read, network request, and subprocess is logged
- Policy enforcement: Block access to
~/.ssh,~/.aws, and other sensitive paths even when the tool doesn't show the access - LLM request visibility: See all API calls the tool makes, with DLP redaction
- Subprocess control: When the tool spawns
npm installorpip installinternally, those are governed too
Add an alias to make this seamless: alias claude='agentsh exec $(agentsh session create --workspace . | jq -r .id) -- claude'
AI Assistant Integration#
There are two approaches to integrating agentsh with AI coding assistants: running the entire agent under agentsh, or configuring the agent to use agentsh for commands.
Running Agents Under agentsh
For unsupervised or autonomous agents, run the entire agent process under agentsh. This ensures comprehensive coverage—every shell command, subprocess, and file operation is monitored and policy-enforced, even if the agent doesn't explicitly use agentsh.
# Create a session with your policy
SID=$(agentsh session create --workspace /path/to/project --policy my-policy | jq -r .id)
# Run Claude Code under agentsh
agentsh exec "$SID" -- claude --dangerously-skip-permissions -p "implement the feature"
# Or run other coding agents
agentsh exec "$SID" -- codex --full-auto "fix the failing tests"
agentsh exec "$SID" -- opencode -p "refactor the auth module"
agentsh exec "$SID" -- cursor-agent --print "add unit tests"
This approach is ideal for:
- Headless/CI pipelines — agents running without human oversight
- Batch operations — processing multiple tasks autonomously
- Defense in depth — policy enforcement regardless of agent behavior
In containerized environments, install the shell shim so that even nested shells and subprocess calls route through agentsh automatically.
Configuring Agents to Use agentsh
For interactive development, configure your AI assistant to route commands through agentsh. This works well when running inside a container isn't practical.
For production or CI/CD environments, prefer running agents in containers with the shell shim installed.
Claude Code
Add to your project's CLAUDE.md:
# Shell access
Run commands via agentsh, not directly in bash/zsh.
Syntax:
agentsh exec SESSION_ID -- COMMAND [ARGS...]
Examples:
agentsh exec my-session -- ls -la
agentsh exec my-session -- npm install
agentsh exec my-session -- go build ./...
With environment variable:
export AGENTSH_SESSION_ID=my-session
agentsh exec -- ls -la
Cursor
Add to your Cursor rules:
All shell commands MUST be executed through agentsh.
Required syntax:
agentsh exec SESSION_ID -- COMMAND [ARGS...]
The -- separator is required between session ID and command.
AGENTS.md
For tools that support the AGENTS.md convention, add the same instructions to your project's AGENTS.md file.
| Flag | Description |
|---|---|
--timeout 30s | Command timeout |
--output json | JSON structured output |
--stream | Stream output as produced |
--pty | Interactive PTY mode |
| Environment Variable | Description |
|---|---|
AGENTSH_SESSION_ID | Default session ID |
AGENTSH_SESSION_ROOT | Root for auto-creating sessions |
AGENTSH_SERVER | Server URL (default: http://127.0.0.1:18080) |
Redirect & Steering#
Most systems can deny an action. agentsh can also redirect it.
When an agent tries the wrong approach (or brute-force workarounds), policy can steer it to the right path by swapping the command and returning guidance—keeping the agent on the paved road and reducing wasted retries.
Redirect curl to an audited wrapper
command_rules:
- name: redirect-curl
commands: [curl, wget]
decision: redirect
message: "Downloads routed through audited fetch"
redirect_to:
command: agentsh-fetch
args: ["--audit"]
Redirect writes outside workspace
file_rules:
- name: redirect-outside-writes
paths: ["/home/**", "/tmp/**"]
operations: [write, create]
decision: redirect
redirect_to: "/workspace/.scratch"
message: "Writes outside workspace redirected to /workspace/.scratch"
Discourage unnecessary deletions
Instead of blocking destructive commands outright, steer the agent away with guidance:
command_rules:
- name: discourage-rm
commands: [rm, rmdir]
args_patterns: ["(-rf?|--recursive)"]
decision: redirect
redirect_to:
command: echo
args: ["Skipped: deletion not needed. Files can remain; they don't affect the build or tests."]
message: "Cleanup is unnecessary—focus on the task instead of removing files."
The agent sees a "successful" cleanup, receives the guidance message, and moves on without wasting retries or attempting workarounds.
The agent sees a successful operation (not an error), but you control where things actually land.
Prevent bypassing merge workflow
Steer agents away from shortcuts that bypass proper code review and merge workflows:
command_rules:
- name: no-direct-push-to-main
commands: [git]
args_patterns: ["push.*(origin\\s+)?(main|master)"]
decision: redirect
redirect_to:
command: echo
args: ["Push declined. Create a branch and open a pull request instead."]
message: "Direct pushes to main/master are not allowed. Use feature branches and pull requests."
- name: no-force-push
commands: [git]
args_patterns: ["push.*(--force|-f)"]
decision: redirect
redirect_to:
command: echo
args: ["Force push blocked. Resolve conflicts through proper merge."]
message: "Force pushing is not allowed—merge changes through the standard workflow."
- name: no-hard-reset
commands: [git]
args_patterns: ["reset.*(--hard)"]
decision: redirect
redirect_to:
command: echo
args: ["Hard reset blocked. Use git stash or git checkout to preserve changes."]
message: "git reset --hard discards uncommitted work. Use non-destructive alternatives."
- name: no-git-clean
commands: [git]
args_patterns: ["clean.*(-f|--force)"]
decision: redirect
redirect_to:
command: echo
args: ["git clean blocked. Untracked files may be needed—review before deleting."]
message: "git clean -fd permanently deletes untracked files. Review them manually first."
The agent receives guidance to use the proper workflow instead of attempting workarounds.
LLM Proxy & DLP#
agentsh includes an embedded proxy that intercepts all LLM API requests from agents.
- Automatic routing: Sets
ANTHROPIC_BASE_URLandOPENAI_BASE_URLso SDKs route through the proxy - Custom providers: Route to LiteLLM, Azure OpenAI, vLLM, or corporate gateways
- DLP redaction: PII (emails, phone numbers, API keys) is redacted before reaching providers
- Usage tracking: Token counts extracted and logged for cost attribution
proxy:
mode: embedded
providers:
anthropic: https://api.anthropic.com
openai: https://api.openai.com
dlp:
mode: redact
patterns:
email: true
api_keys: true
custom_patterns:
- name: customer_id
display: identifier
regex: "CUST-[0-9]{8}"
Session Reports#
Generate markdown reports summarizing session activity for auditing, debugging, and compliance.
# Quick summary of latest session
agentsh report latest --level=summary
# Detailed investigation with full timeline
agentsh report <session-id> --level=detailed --output=report.md
# JSON output for programmatic processing
agentsh report latest --level=summary --format=json
Report Levels
| Level | Contents |
|---|---|
summary | Overview, activity counts, security findings, decision summary |
detailed | Everything in summary plus command history, file access, network connections, resource usage, and full event timeline |
Example Summary Report
# Session Report: sess-abc123
**Generated:** 2025-01-15T10:31:00Z
**Report Level:** Summary
## Session Overview
| Property | Value |
|----------|-------|
| Session ID | sess-abc123 |
| Duration | 25s |
| Workspace | /home/user/project |
## Activity Summary
| Metric | Count |
|--------|-------|
| Commands Executed | 6 |
| Files Accessed | 1 |
| Network Connections | 2 |
| Policy Denials | 2 |
## Security Findings
### Critical
- **Dangerous command blocked**: `rm -rf /` - rm -rf blocked for safety
### Warning
- **Network access denied**: Connection to `internal.corp.local:80` blocked
## Policy Decisions
| Decision | Count |
|----------|-------|
| Allow | 5 |
| Deny | 2 |
| Redirect | 0 |
Example Detailed Report (excerpt)
## Command History
| Time | Command | Decision | Exit Code | Duration |
|------|---------|----------|-----------|----------|
| 10:30:01 | `ls -la` | allow | 0 | 126ms |
| 10:30:05 | `git status` | allow | 0 | 149ms |
| 10:30:15 | `rm -rf /` | **deny** | - | - |
| 10:30:20 | `curl https://api.github.com` | allow | 0 | 499ms |
## Network Connections
| Time | Domain | Port | Decision | Rule |
|------|--------|------|----------|------|
| 10:30:20 | api.github.com | 443 | allow | github.com allowed |
| 10:30:25 | internal.corp.local | 80 | **deny** | internal networks blocked |
## Event Timeline
```
10:30:00.000 [session_created] Session started in /home/user/project
10:30:01.123 [command_policy] ls -la → allow
10:30:15.000 [command_policy] rm -rf / → DENY (rm -rf blocked)
10:30:20.010 [net_connect] api.github.com:443 → allow
10:30:25.010 [net_connect] internal.corp.local:80 → DENY
```
Workspace Checkpoints#
Create snapshots of workspace state for recovery from destructive operations:
# Create a checkpoint before risky operations
agentsh checkpoint create --session $SID --workspace /workspace --reason "before cleanup"
# List checkpoints for a session
agentsh checkpoint list --session $SID
# Preview what rollback would restore (dry-run)
agentsh checkpoint rollback <cp-id> --session $SID --workspace /workspace --dry-run
# Restore workspace to checkpoint state
agentsh checkpoint rollback <cp-id> --session $SID --workspace /workspace
When enabled, agentsh automatically creates checkpoints before risky commands (rm, mv, git reset, etc.). Configure in sessions.checkpoints.auto_checkpoint.
Policy Generation#
The profile-then-lock workflow lets you generate restrictive policies from observed session behavior. Run your workload once in permissive mode, then lock down future runs to only what was observed.
The Profile-Then-Lock Workflow
1. Profile
Run your build/test/agent task with a permissive policy. agentsh records every operation.
2. Generate
Use the recorded session to generate a policy that allows only what was observed.
3. Lock
Apply the generated policy to future runs. Any deviation is blocked or flagged.
4. Iterate
If legitimate behavior is blocked, re-profile and regenerate.
Generating a Policy
# Step 1: Run your workload (profile phase)
SID=$(agentsh session create --workspace . --policy permissive | jq -r .id)
agentsh exec "$SID" -- npm install
agentsh exec "$SID" -- npm run build
agentsh exec "$SID" -- npm test
# Step 2: Generate policy from observed behavior
agentsh policy generate "$SID" --output=ci-locked.yaml --name=ci-build
# Step 3: Use the locked policy for future runs
SID=$(agentsh session create --workspace . --policy ci-build | jq -r .id)
agentsh exec "$SID" -- npm install # Only allowed packages from profile
Generation Options
| Flag | Description |
|---|---|
--output | Write policy to file (default: stdout) |
--name | Policy name (default: generated-<session-id>) |
--threshold | Minimum occurrences before including a path pattern (default: 1) |
--include-blocked | Include blocked operations as commented-out rules for review |
What Gets Generated
The generated policy:
- File rules: Allows only paths that were accessed, grouped into globs (e.g.,
/workspace/src/**/*.ts) - Network rules: Allows only domains/IPs that were contacted, with subdomain wildcards (e.g.,
*.github.com) - Command rules: Flags risky commands (
curl,wget,rm) with the exact arg patterns observed - Comments: Documents why each rule exists with session timestamp
Example Generated Policy
# Generated from session sess-abc123 on 2025-01-15
# Profile: npm install && npm run build && npm test
version: 1
name: ci-build
file_rules:
- name: workspace-src
paths: ["/workspace/src/**"]
operations: [read, open, stat, list]
decision: allow
- name: workspace-dist
paths: ["/workspace/dist/**"]
operations: [read, write, create, mkdir]
decision: allow
- name: node-modules
paths: ["/workspace/node_modules/**"]
operations: ["*"]
decision: allow
network_rules:
- name: npm-registry
domains: ["registry.npmjs.org", "*.npmjs.org"]
ports: [443]
decision: allow
- name: default-deny
domains: ["*"]
decision: deny
Use Cases
- CI/CD lockdown: Profile a build/test run, lock future runs to that exact behavior
- Agent sandboxing: Let an AI agent run a task once, generate policy for future runs
- Container profiling: Profile a workload, generate minimal policy for production
- Compliance: Document exactly what a process does and enforce it doesn't change
Authentication#
agentsh supports multiple authentication methods:
| Type | Use Case |
|---|---|
api_key | Simple deployments with static keys |
oidc | Enterprise SSO (Okta, Azure AD, etc.) |
hybrid | Both methods accepted |
Approval modes for human-in-the-loop verification:
local_tty- Terminal prompt (default)totp- Authenticator app codeswebauthn- Hardware security keys (YubiKey)api- Remote approval via REST
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.
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
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
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
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
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
See the GitHub repository for more examples, the full spec, and to report issues.