Rule Engine
Warden ships with over 300 compiled rules organized into categories:
| Category | Examples |
|---|---|
| Safety | Block rm -rf, sudo, chmod 777, force pushes, credential file writes |
| Substitution | Redirect grep → rg, find → fd, curl → xh, cat → bat |
| Hallucination | Detect invented CLI flags, non-existent subcommands, wrong argument patterns |
| Path protection | Prevent writes to .env, credentials, system files, lock files |
| Git policy | Block mutating git commands (push, merge, rebase) unless explicitly allowed |
| Advisory | Suggest better approaches, warn about large file reads, flag verification debt |
Rules are compiled into the binary — no runtime parsing, no config files to maintain. New rules ship with every release.
How Rules Are Compiled
Every rule pattern lives in Rust source files under config/core/ — one file per category. At compile time, these become static arrays baked into the binary. There’s no TOML to parse at startup, no file to read from disk, and no way for a misconfigured file to break your protection.
This design means:
- Zero startup cost. Rules are available the instant the binary loads.
- No external dependencies. The rules can’t go missing, get corrupted, or fail to download.
- Version-locked. When you update Warden, you get the exact rule set that was tested against that version.
You can extend the compiled rules with TOML overrides (see Configuration), but the compiled floor is always present.
RegexSet DFA Matching
Warden doesn’t evaluate rules one by one. All patterns in a category are compiled into a single RegexSet, which builds a deterministic finite automaton (DFA). When a command comes in, the DFA evaluates all 300+ patterns in a single pass over the input string.
This is why Warden can evaluate hundreds of rules in under 2 milliseconds. The cost of matching doesn’t grow linearly with the number of rules — the DFA processes each character of the input exactly once, regardless of how many patterns exist.
Rule Categories in Detail
Safety — universally dangerous operations that are always blocked:
rm -rfon broad paths (~,/,.,*)- Privilege escalation (
sudo,su -,doas,runas) - Dangerous permissions (
chmod 777,chmod -R 777,chmod a+w) - System damage (
mkfs,dd if=,format C:,diskpart) - Process killing (
kill -9 1,killall,pkill -9) - Environment destruction (
export PATH=,unset PATH)
Substitution — redirects legacy tools to modern alternatives:
greptorg(ripgrep) — 10-50x faster regex searchfindtofd— faster file discovery with sane defaultscurltoxh— friendlier HTTP client with colored outputcattobat— syntax highlighting and line numbersdutodust— visual disk usage treetar/zip/unzip/gziptoouch— auto-detecting archive toolsort | uniqtohuniq— faster, preserves insertion ordersdblocked on Windows — mangles newlines, use the Edit tool instead
Hallucination — catches commands the agent fabricated:
- URL-encoded path traversal (
%2e%2e/) - Null byte injection (
\x00,%00) - Reverse shell patterns (
/dev/tcp/,socat EXEC:,ncat -e) - Credential exfiltration (piping
.ssh/id_rsaor.envtocurl/wget) - Command hijacking (
alias sudo=...,eval $(curl ...)) - Base64-decoded command execution
Path protection — prevents writes to sensitive locations:
- SSH keys and config (
~/.ssh/) - GPG keys (
~/.gnupg/) - Cloud credentials (
~/.aws/credentials,~/.azure/,~/.kube/config,~/.gcloud/) - Docker credentials (
~/.docker/config.json) - System directories (
/etc/,/usr/,C:\Windows,C:\Program Files) - Certificate and key files (
.pem,.key,.p12,.pfx) - Terraform state (
~/.terraform/)
Git policy — enforces read-only git by default:
- Blocks
git push,git merge,git rebase,git reset - Blocks
git checkout,git restore,git cherry-pick - Blocks
git stash(save),git branch -d/-D,git tag - Allows read-only commands:
log,status,diff,show,branch(list),blame
Advisory — non-blocking hints for better practices:
- Docker CLI usage when MCP tools are available
rgfor symbol lookups when aidex is availablergfor structural patterns when ast-grep is availablenpm install,cargo add,pip installwarnings about environment modificationgit clonewarnings about disk space and time
Shadow Mode
Rules can be set to shadow mode, where they log what they would have done without actually blocking. This is useful for:
- Testing new rules before deploying them in production. Add a custom rule with
shadow = truein yourrules.tomland watch the logs to see if it would fire correctly. - Auditing which rules are active. Shadow-mode rules appear in logs and statistics but don’t affect the agent’s workflow.
# In ~/.warden/rules.toml
[safety]
patterns = [
{ match = "some-new-pattern", msg = "Testing this rule", shadow = true }
]
Shadow-mode entries show up in warden stats and warden export data, so you can evaluate their accuracy before making them live.
Rule IDs
Every rule has a stable ID composed of its category and index. Examples:
| ID | Rule |
|---|---|
safety.0 | Block rm -rf on broad paths |
safety.3 | Block sudo |
substitution.0 | Redirect grep to rg |
substitution.1 | Redirect find to fd |
hallucination.4 | Block reverse shell patterns |
sensitive_deny.0 | Block writes to .ssh/ |
Rule IDs are used for:
- Disabling rules in config:
disabled = ["substitution.0"] - Explaining rules:
warden explain safety.3 - Filtering stats: seeing how often a specific rule fires
Viewing All Rules
warden describe --all
This prints every active rule with its ID, category, severity (HardDeny, SoftDeny, or Advisory), pattern, message, and whether it can be disabled. Safety rules marked as HardDeny cannot be disabled — they’re the immutable floor of protection.