Getting Started
Get policy enforcement on your AI coding agents in under two minutes.
Quick start (AI agents)
curl -fsSL https://warrant.sh/install.sh | sudo sh
wsh setup codex That’s it. wsh setup installs manifests, locks the policy, adds shell aliases, and installs a guard hook. After setup, run codex or claude — every command is policy-enforced and audited. See the integration guide for details.
Manual setup
If you prefer to build your policy step by step, or need more control:
Install warrant-shell
The fastest way to install is with the one-liner. For full functionality (including the audit daemon), run with sudo:
curl -fsSL https://warrant.sh/install.sh | sudo sh This detects your OS and architecture, downloads the prebuilt binaries (wsh and wsh-auditd), installs them, and sets up the audit daemon as a system service (systemd on Linux, launchd on macOS).
User-mode install (no daemon)
If you don't have root access, you can install just the wsh binary:
curl -fsSL https://warrant.sh/install.sh | sh This installs to ~/.local/bin/wsh. Audit logging falls back to direct file writes, which is fine for development but not recommended for production use.
Alternative: install via Cargo
If you have Rust installed, you can also build from source:
cargo install wsh Note: building from source only installs the wsh binary. For the audit daemon, use the install script with sudo.
Verify it's working:
wsh --version Global guard (optional)
By default, the warrant only guards commands run by your agent. For dedicated agent machines, enable global guard so that all shell sessions are policy-checked:
wsh setup codex
wsh guard --all # guard all shell sessions
wsh elevate --duration 60 # temporary unrestricted access when needed This adds export WSH_GUARD=1 to ~/.zshenv, so every command on the machine is policy-enforced. Check or disable at any time with wsh guard and wsh guard --off.
Adding language support
After wsh setup, interpreters like Python, Node.js, and Ruby are denied by default. This is deliberate — each interpreter you add opens an attack vector, because an agent with Python access can use the standard library to read files, make network requests, and spawn processes that bypass wsh entirely.
Add only what your project needs:
wsh add python # grants python3, pytest, ruff, mypy, etc.
wsh add node # grants node, npx, tsc, eslint, etc.
wsh add rust # grants rustc, cargo, clippy, etc.
sudo wsh lock # seal the updated policy Each language manifest includes the interpreter plus common development tooling for that ecosystem, with sensible defaults. Publishing commands (twine, npm publish) are denied by default.
Step 1: Add a manifest
Manifests are declarative capability maps that describe what a CLI tool can do. The registry includes manifests for common tools (git, cargo, npm, curl, docker, ssh, pip) and languages (python, node, rust, ruby). Add one to create a draft policy:
wsh add git This creates a draft policy file from the git manifest. The draft lives in your config directory and lists every capability that git has — clone, push, push_force, commit, and so on — each initially set to review.
You can specify whether the draft is system-wide or project-scoped:
wsh add git --scope system # default — applies everywhere
wsh add git --scope project # applies only to the current project Step 2: Edit the draft policy
Open the draft in your editor to set allow/deny decisions for each capability:
wsh edit git This opens the draft TOML file in $EDITOR. You'll see each capability listed. Set each one to allow, deny, or leave as review:
# Example draft — git.toml
[capabilities.git]
clone = "allow"
fetch = "allow"
push = "allow"
push_force = "deny"
commit = "allow"
branch = "allow"
merge = "allow"
rebase = "deny"
reset = "deny"
stash = "allow"
tag = "review"
remote = "deny"
log = "allow"
diff = "allow"
status = "allow"
checkout = "allow" Important: The lock step will refuse to compile if any capability is still set to review. Every capability must be explicitly allowed or denied. This forces conscious decisions — no accidental permissiveness.
Step 3: Lock the policy
Once every capability has a decision, compile and sign the policy:
sudo wsh lock This requires elevated privileges because the lock step:
- Reads all draft policies from your config directory
- Validates them against their manifests
- Compiles them into a single signed policy
- Signs the policy with an Ed25519 key stored in a root-owned path
- Installs the signed policy to
/etc/warrant-shell/ - Increments the monotonic version number (preventing rollback)
You can also lock a single tool's policy:
sudo wsh lock git Step 4: Wire up your agent
To make enforcement transparent, wire your agent so it runs normal commands through wsh automatically. From the agent's perspective, it should execute commands like this:
# Allowed — git.push is granted
git push origin main
# Denied — git.push_force is not granted
git push --force origin main How to wire it up (briefly):
- Recommended: run the agent in
warrant-box - Lightweight: set
SHELL=/usr/local/bin/wshfor agents that respect it - Advanced: use PATH wrappers or agent-specific executor configuration
Full integration methods and security trade-offs are covered in Integrating with AI Agents.
Step 5: Check without executing
Want to test what would happen without actually running the command? Use check:
wsh check git push --force origin main
# Output: denied — capability "git.push_force" not granted Step 6: Review the audit log
Every decision — allowed or denied — is logged. In system mode, audit events are written to a privileged daemon (wsh-auditd) that maintains a tamper-evident, hash-chained ledger. View the audit trail:
# Show last 20 entries (default)
wsh audit
# Show last 50 entries
wsh audit --tail 50
# Output as JSON Lines (for piping to jq, etc.)
wsh audit --json
# Verify the integrity of the audit hash chain
wsh audit verify
# Clear the audit log
wsh audit --clear Audit entries include the timestamp, command, matched capability, decision, policy version, session ID, and a SHA-256 hash linking each entry to its predecessor for tamper detection.
Step 7: Check policy status
See the current state of your warrant at any time:
wsh status This shows the active policy version, which tools are covered, and the current enforcement state.
What's next
- Integrating with AI Agents — transparent agent wiring patterns and security levels
- Concepts — understand manifests, drafts, lock compilation, and the two-tier scope system
- CLI Reference — every wsh command and flag
- Manifest Specification — write custom manifests for any tool
- Security Model — what wsh protects against (and what it doesn't)