Wardenby Bitmill
Documentation

Rule Engine

Warden ships with ~300 compiled patterns organized into categories:

CategoryExamples
SafetyBlock rm -rf, sudo, chmod 777, force pushes, credential file writes
SubstitutionRedirect greprg, findfd, curlxh, catbat
HallucinationDetect invented CLI flags, non-existent subcommands, wrong argument patterns
Path protectionPrevent writes to .env, credentials, system files, lock files
Git policyBlock mutating git commands (push, merge, rebase) unless explicitly allowed
AdvisorySuggest 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 -rf on 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:

  • grep to rg (ripgrep) — 10-50x faster regex search
  • find to fd — faster file discovery with sane defaults
  • curl to xh — friendlier HTTP client with colored output
  • cat to bat — syntax highlighting and line numbers
  • du to dust — visual disk usage tree
  • tar/zip/unzip/gzip to ouch — auto-detecting archive tool
  • sort | uniq to huniq — faster, preserves insertion order
  • sd blocked 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_rsa or .env to curl/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
  • rg for symbol lookups when aidex is available
  • rg for structural patterns when ast-grep is available
  • npm install, cargo add, pip install warnings about environment modification
  • git clone warnings 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 = true in your rules.toml and 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:

IDRule
safety.0Block rm -rf on broad paths
safety.3Block sudo
substitution.0Redirect grep to rg
substitution.1Redirect find to fd
hallucination.4Block reverse shell patterns
sensitive_deny.0Block 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.