omamori 0.3.1

AI Agent's Omamori — protect your system from dangerous commands executed via AI CLI tools
Documentation

omamori

Pre-1.0 — Breaking changes may occur between minor versions.

AI Agent's Omamori — protect your system from dangerous commands executed via AI CLI tools.

Supported AI CLI Tools

Tool Detection Status
Claude Code CLAUDECODE=1 Verified
Codex CLI CODEX_CI=1 Verified
Cursor CURSOR_AGENT=1 Provisional
Gemini CLI GEMINI_CLI=1 Provisional
Cline CLINE_ACTIVE=true Provisional
Any tool setting AI_GUARD=1 AI_GUARD=1 Fallback

Detection uses exact value matching (e.g. CLAUDECODE=1 only, not CLAUDECODE=true). Tools that set these environment variables when executing shell commands are automatically detected.

What It Does

When an AI CLI tool (Claude Code, Codex, Cursor, etc.) runs a shell command, omamori intercepts dangerous operations and replaces them with safe alternatives. Terminal direct execution is not affected.

[AI CLI Tool] → CLAUDECODE=1 → rm -rf target/
                                  ↓
                            [omamori shim]
                                  ↓
                         moved to Trash instead
[Terminal]    →              → rm -rf target/
                                  ↓
                            [/usr/bin/rm]
                                  ↓
                            deleted normally

Quick Start

Install via Homebrew (macOS)

brew install yottayoshida/tap/omamori

Or build from source

cargo install --path .

Setup

# 1. Install shims + hooks + config (all in one command)
omamori install --hooks

# 2. Add shim directory to PATH (add to .zshrc / .bashrc)
export PATH="$HOME/.omamori/shim:$PATH"

That's it. install --hooks auto-generates config.toml, runs verification, and shows a checklist:

omamori setup complete:

Shims:
  [done] rm, git, chmod, find, rsync

Hooks:
  [done] Claude Code hook script
  [done] Cursor hook snippet

Config:
  [done] Created: ~/.config/omamori/config.toml
  [done] 7 rules verified, 10 detection tests passed

Next steps:
  [todo] Add to your shell profile:
    export PATH="$HOME/.omamori/shim:$PATH"
  [todo] Merge Cursor hook into .cursor/hooks.json

How It Works

Layer 1 — PATH shim: Symlinks for rm, git, chmod, find, rsync point to the omamori binary. When invoked, omamori checks for AI tool environment variables (e.g. CLAUDECODE=1) and applies rules only if an AI tool is detected.

Layer 2 — Hooks (optional):

  • Claude Code: A PreToolUse hook script catches bypass attempts like /bin/rm direct paths, unset CLAUDECODE, and warns on interpreter commands (python -c "shutil.rmtree(...)").
  • Cursor: A Rust-native beforeShellExecution handler (omamori cursor-hook) provides the same protection via Cursor's hook protocol.

Default Rules

Command Pattern Action
rm -r, -rf, -fr, --recursive trash — move to macOS Trash
git reset --hard stash-then-execgit stash first, then execute
git push --force, push -f block
git clean -fd, clean -fdx block
chmod 777 block
find -delete, --delete block
rsync --delete and 7 variants block

Combined short flags are normalized: rm -rfv expands to match -r and -rf rules. The POSIX -- separator is respected for target extraction.

Configuration (v0.2+)

Built-in rules are always inherited. Config is auto-created by install --hooks. To regenerate manually:

omamori init              # Creates ~/.config/omamori/config.toml (chmod 600)
omamori init --force      # Overwrite existing config
omamori init --stdout     # Print template to stdout (backward compat)

Disable a rule via CLI (v0.3+):

omamori config disable git-push-force-block
omamori config enable git-push-force-block    # restore built-in default
omamori config list                           # show all rules with status

Or edit config.toml directly:

[[rules]]
name = "git-push-force-block"
enabled = false

Move files to a custom directory instead of Trash:

[[rules]]
name = "rm-to-backup"
command = "rm"
action = "move-to"
destination = "/tmp/omamori-quarantine/"
match_any = ["-r", "-rf", "-fr", "--recursive"]
message = "omamori moved targets to quarantine instead of deleting"

Override an existing rule's action:

[[rules]]
name = "rm-recursive-to-trash"
action = "move-to"
destination = "/tmp/omamori-quarantine/"

After editing, run omamori test to verify. Disabled rules show as SKIP:

Rules:
  PASS  rm-recursive-to-trash        rm -r|-rf|-fr|--recursive -> trash
  SKIP  git-push-force-block         (disabled by user config)
  ...
Summary: 5 rules (4 active, 1 disabled), 4 detection tests passed

Configuration notes

  • Config file requires chmod 600 (permissions check enforced)
  • Only write rules you want to change — everything else is inherited
  • destination must be an absolute path on the same volume
  • System directories (/usr, /etc, /System, /Library, /bin, /sbin, /var, /private) are blocked as destinations
  • Symlinks are rejected as destinations
  • destination directory must exist before use (omamori will not create it)

Available Actions

Action Behavior
trash Move targets to macOS Trash
move-to Move targets to a user-specified directory (requires destination)
stash-then-exec Run git stash first, then execute the original command
block Refuse to execute
log-only Log the event, then execute normally

Safe Defaults

Scenario Behavior
No AI env var detected Pass through to real command (no interference)
Config file missing Fail-close: built-in default rules apply
Config file broken Fail-close: built-in default rules apply + warning
Trash / move-to fails Fail-close: refuse to run the original command
sudo detected Block the command
Blocked destination Fail-close: rule is disabled at config load time
Shim binary crashes Fail-open: real command runs

CLI

omamori test [--config PATH]                          # Verify policy rules
omamori exec [--config PATH] -- <command> [args...]   # Run through policy engine
omamori install [--base-dir PATH] [--hooks]           # Create shims + hooks + config
omamori uninstall [--base-dir PATH]                   # Remove shims + hook files
omamori init [--force] [--stdout]                     # Create/reset config file
omamori config list                                   # Show all rules with status
omamori config disable <rule>                         # Disable a built-in rule
omamori config enable <rule>                          # Re-enable a disabled rule
omamori cursor-hook                                   # Cursor beforeShellExecution handler

Structural Limitations

These are inherent to the PATH shim approach and documented honestly:

  • Full-path execution (/bin/rm, /usr/bin/git) bypasses the shim — mitigated by Layer 2 hooks (Claude Code + Cursor)
  • sudo changes PATH before the shim runs — omamori blocks when it detects elevated execution in-process
  • Interpreter commands (python -c "shutil.rmtree(...)") — Layer 2 hooks warn on known destructive patterns, but obfuscated code (base64, heredoc, variable indirection) cannot be detected
  • find -exec /bin/rm bypasses the find shim because rm is invoked via absolute path — partially mitigated by Layer 2 hooks
  • Cross-device moves are not supported for move-to (use a destination on the same volume)

For the full security model, see SECURITY.md.

Related

  • nanika — explains what AI commands will do (detect + translate). Complementary to omamori (detect + replace).

License

Licensed under either of Apache License, Version 2.0 or MIT license at your option.