Agentsh
Execution-Layer Security (ELS) for AI agents — policy-enforced shell with audit.
Install / Use
/learn @canyonroad/AgentshREADME
agentsh
macOS note: Native macOS enforcement via ESF (Endpoint Security Framework) + NE (Network Extension) is in Alpha. It works end-to-end — file, process, and network events flow through the system extension to the Go policy engine — but expect rough edges and breaking changes between releases. For production use today, we recommend Linux.
Windows note: We are working to get the minifilter drivers signed. Until then, only Windows WSL2 mode is fully supported for production use.
Secure, policy-enforced execution gateway for AI agents.
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.
Platform note: Linux provides full enforcement (100% security score). macOS ESF+NE (90% score) is in Alpha — functional but not production-ready. Windows WSL2 provides full Linux-equivalent enforcement (100% score); native Windows via minifilter driver + AppContainer (85% score) is pending driver signing. See the Platform Comparison Matrix for details.
What is agentsh?
- Drop-in shell/exec endpoint that turns every command (and its subprocesses) into auditable events.
- Per-operation policy engine:
allow,deny,approve(human OK),soft_delete, orredirect. - Full I/O visibility:
- file open/read/write/delete
- network connect + DNS
- process start/exit
- PTY activity
- LLM API requests with DLP and usage tracking
- signal send/block (Linux enforced, macOS/Windows audit)
- Two output modes:
- human-friendly shell output
- compact JSON responses for agents/tools
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.
Meaningful blocks: deny → redirect (the "steering" superpower)
Most systems can deny an action. agentsh can also redirect it.
That means 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.
Example: 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"]
Example: redirect writes outside workspace back inside
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"
The agent sees a successful operation (not an error), but you control where things actually land.
Containers + agentsh: better together
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—not just the first command.
- Path-level controls on mounted workspaces/caches/creds; containers don't natively give that granularity.
- Same behavior on host and in containers, so CI and local dev see the same policy outcomes.
Quick start
Install
macOS (Homebrew)
brew tap canyonroad/tap
brew install --cask agentsh
This installs the AgentSH app bundle with the ESF+NE system extension. After installation you'll be prompted to approve the system extension in System Settings > General > Login Items & Extensions.
Linux (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)
# ESF+NE mode (full enforcement — Alpha, requires Xcode 15+)
make build-macos-enterprise
See macOS Build Guide for detailed macOS build instructions.
Run locally
# Start the server (optional if using autostart)
./bin/agentsh server --config configs/server-config.yaml
# Create a session and run a command (shell output)
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
Tell your agent to use it (AGENTS.md / CLAUDE.md snippet)
## Shell access
- Run commands via agentsh, not directly in bash/zsh.
- Use: `agentsh exec $SID -- <your-command-here>`
- For structured output: `agentsh exec --output json --events summary $SID -- <your-command-here>`
- Get session ID first: `SID=$(agentsh session create --workspace . | jq -r .id)`
Autostart (no manual daemon step)
You do not need to start agentsh server yourself.
- The first
agentsh exec(or any shimmed/bin/sh//bin/bash) will automatically launch a local server usingconfigs/server-config.yaml(orAGENTSH_CONFIGif set). - That server keeps the FUSE layer and policy engine alive for the session lifetime; subsequent commands reuse it.
- Set
AGENTSH_NO_AUTO=1if you want to manage the server lifecycle manually.
Use in Docker (with the shell shim)
See Dockerfile.example for a minimal Debian-based image.
Inside the image, install a release package (or copy your build), then activate the shim:
agentsh shim install-shell \
--root / \
--shim /usr/bin/agentsh-shell-shim \
--bash \
--i-understand-this-modifies-the-host
Point the shim at your server (sidecar or host):
ENV AGENTSH_SERVER=http://127.0.0.1:18080
Now any /bin/sh -c ... or /bin/bash -lc ... in the container routes through agentsh.
Non-interactive enforcement
By default, the shim bypasses policy when stdin is not a TTY (preserving binary data for piped commands). On platforms where commands are always non-interactive but still need enforcement (e.g., exe.dev, sandbox APIs), add --force:
agentsh shim install-shell \
--root / \
--shim /usr/bin/agentsh-shell-shim \
--bash \
--force \
--i-understand-this-modifies-the-host
This writes /etc/agentsh/shim.conf with force=true, which the shim reads at startup. The config file works regardless of how the shell is spawned (unlike env vars or profile scripts). AGENTSH_SHIM_FORCE=1 in the process environment achieves the same effect per-process.
Recommended pattern: 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.
Policy model
Decisions
allowdenyapprove(human OK)redirect(swap a command)audit(allow + log)soft_delete(quarantine deletes with restore)
Scopes
- file operations
- commands
- environment vars
- network (DNS/connect)
- PTY/session settings
Evaluation
- first matching rule wins
Rules live in a named policy; sessions choose a policy.
Defaults:
- sample config:
configs/server-config.yaml - default policy:
configs/policies/default.yaml - env override: set
AGENTSH_POLICY_NAMEto an allowed policy name (no suffix). If unset/invalid/disallowed, the default is used. - env policy: configure
policies.env_policy(allow/deny, max_bytes, max_keys, block_iteration) and per-commandenv_*overrides in policy files. Empty allowlist defaults to minimal PATH/LANG/TERM/HOME with built-in secret deny list; setblock_iterationto hide env iteration (requires env shim). - allowlist: configure
policies.allowedinconfig.yml; empty means only the default is permitted. - optional integrity: set
policies.manifest_pathto a SHA256 manifest to verify policy files at load time.
Environment policy quick reference
- 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_denyplusenv_max_keys/env_max_bytescap and filter the child env at exec time. - Block iteration:
env_block_iteration: true(global or per rule) hides env enumeration; setpolicies.env_shim_pathtolibenvshim.soso agentsh injectsLD_PRELOAD+AGENTSH_ENV_BLOCK_ITERATION=1. - Limits: Errors if limits are exceeded; env builder is applied before exec for every command.
- env_inject: Operator-trusted environment variables injected into all commands, bypassing policy filtering. Primary use:
BASH_ENVto disable shell builtins that bypass seccomp. Configure insandbox.env_inject(global) or policy-levelenv_inject(overrides global). - Examples: See
config.ymland policy samples underconfigs/.
Example rules (trimmed)
version: 1
name: default
file_rules:
- name: allow-workspace
paths: ["/workspace", "/workspace/**"]
operations: [read, open, stat, list, write, create, mkdir, chmod, rename]
decision: allow
- name: approve-workspace-delete
paths: ["/workspace", "/workspace/**"]
operations: [delete, rmdir]
decision: approve
message: "Delete {{.Path}}?"
timeout: 5m
- name: deny-ssh-keys
paths: ["/home/**/.ssh/**", "/root/.ssh/**"]
operations: ["*"]
decision: de
Related Skills
node-connect
352.9kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
111.5kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
352.9kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
352.9kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
