Command protection tool — guards rm, mv, chmod with confirmation, automatic backup, and undo.
cmdguard wraps dangerous commands (rm, mv, chmod) to prevent accidental data loss.
- 🚫 Four protection levels — reject, confirm_double, confirm, warn
- 💾 Automatic backup — files are copied to a vault before destructive ops
- ↩️ Undo — restore deleted or overwritten files via
cmdguard undo - 📋 Audit log — every operation is recorded permanently; searchable & filterable
- 🤖 Agent-aware — explicit handling for AI agents and automation (see below)
- ⚙️ TOML config — glob path patterns, per-command overrides
Add aliases to ~/.zshrc or ~/.bashrc:
alias rm='cmdguard rm'
alias mv='cmdguard mv'
alias chmod='cmdguard chmod'Put ~/.cmdguard/bin/ at the front of PATH so the agent's rm/mv/chmod
lookups hit cmdguard's wrappers:
export PATH="$HOME/.cmdguard/bin:$PATH"
export CMDGUARD_NONINTERACTIVE=1 # skip the 5s/10s confirm waitBoth methods can coexist.
cmdguard cannot intercept calls that bypass PATH lookup, e.g. /bin/rm /etc/passwd.
The model is "protect + audit + recoverable", not "absolute lockdown".
When an AI agent invokes a guarded command and the target is a protected path, cmdguard refuses to hang on an interactive prompt. The agent must:
-
Set the env var to declare itself non-interactive:
export CMDGUARD_NONINTERACTIVE=1This skips the 5s/10s wait at confirm prompts. It does NOT grant permission — the operation is still rejected.
-
If the operation is genuinely safe, retry with a
--bypassidentifier:rm /path/to/file --bypass=<host>/<platform>/<agent>/<task>
The identifier must have exactly 4 segments:
segment meaning example host machine hostname / alias mac-studioplatform agent platform qwenpaw,cursoragent agent id ai_researchtask brief task slug cleanup-tmp-dirsAllowed characters:
[a-zA-Z0-9._-]. Empty segments, angle brackets, and template placeholder words (host,agent,task,xxx,foo,todo, ...) are rejected.
Every bypass is recorded in the audit log with the full identifier, so the audit trail attributes every protected-path operation back to a specific agent / task.
See docs/commands.md for full details.
# Option 1 — pre-built binary (recommended)
# Download from the Releases page for your platform.
# Option 2 — build from source
git clone https://github.com/hyper0x/cmdguard.git
cd cmdguard
make install # installs to $GOBIN with version info baked incmdguard initCreates ~/.cmdguard/{config.toml, bin/, log/, vault/} and prints the
integration guide. Idempotent — re-running is safe. Use --force to
overwrite (old files are zipped to ~/.cmdguard/backup/).
| Command | Description |
|---|---|
rm/mv/chmod <args...> |
Run a command through cmdguard |
init [--force] [--dry-run] |
Initialize the environment |
list [options] |
List audit log entries |
undo [options] |
Restore an operation from vault |
vault clean [--dry-run] |
Purge expired vault backups |
config |
Print the active configuration |
help / version |
Self-explanatory |
Full reference: docs/commands.md
Location: ~/.cmdguard/config.toml (overridable via CMDGUARD_CONFIG_DIR).
[protect]
reject = ["/etc/**", "/private/**", "~/.ssh/**"]
confirm_double = ["~/.config/**"]
confirm = ["~/Documents/**", "~/Desktop/**"]
warn = ["~/Downloads/**"]
[vault]
retention_days = 7
auto_purge = true
[guard]
confirm_timeout = 5 # seconds; 'confirm' prompt
confirm_double_timeout = 10 # seconds per step; 'confirm_double' promptThe config file is read-only from cmdguard's perspective. cmdguard never modifies it at runtime; only
cmdguard init --forcemay overwrite it (with a backup zip).
Full reference: docs/configuration.md
- Backup directory:
~/.cmdguard/vault/<timestamp>_<id>/ - Retention: 30 days by default, configurable
- Restore:
cmdguard undo [--id <id>] [--interactive] [--dry-run] - Logs: permanent, JSON, one file per day
Details: docs/vault.md
git clone https://github.com/hyper0x/cmdguard.git
cd cmdguard
make build # build into ./dist with version from git tag
make install # install to $GOBINCan cmdguard be bypassed?
Yes. /bin/rm /etc/passwd skips the PATH lookup entirely. cmdguard is
protection + audit + recovery, not an absolute lockdown.
What's the difference between confirm and confirm_double?
confirm requires a single y. confirm_double requires y first and
then typing the full word yes — designed to defeat fatigue errors on
high-risk paths.
What if my config file gets overwritten?
cmdguard init never overwrites without --force. With --force, the
old file is preserved at ~/.cmdguard/backup/init-<timestamp>.zip.
Where do agents put CMDGUARD_NONINTERACTIVE?
In the agent's shell init or wherever the agent's environment is set up.
Once exported, every cmdguard call in that environment skips the wait
and goes straight to the bypass-or-reject path.
How do I uninstall?
# Remove the alias / PATH line from your shell rc, then:
trash ~/.cmdguard # or rm -rf if you don't have trash
rm $(which cmdguard)