Install
openclaw skills install @cengcengcai-creator/agent-command-guard-hardeningHarden an agent's command interception layer safely: snapshot the baseline, test a matrix of should-block, negative-control, and known-bypass cases, verify classification rather than executing destructive commands, and document the bypass surface. Use when adding or changing guards around rm, mv, chmod, sudo, launchctl, dd, or any command wrapper. Tool-agnostic; includes a matrix runner and a bypass scanner.
openclaw skills install @cengcengcai-creator/agent-command-guard-hardeningChanging a guard is a safety change, and safety changes need evidence. This skill makes the evidence reproducible: baseline first, matrix before and after, negative controls always, bypass surface stated.
Developed through agent operation and corrected against real failures, not hand-authored as a prompt template.
Use for
bash -c, interpreter one-liners).Do not use for
Required: a place to store the baseline, a way to invoke the classifier without executing the command, and the ability to restore the previous wrapper.
Known limits:
PATH cannot stop absolute-path invocation unless the filesystem denies it.bash -c, python -c, eval) can reconstruct any command.PATH.Never claim a bypass is closed when it is only narrowed. State the residual surface.
Snapshot, in a timestamped directory:
PATH and which -a for every controlled command.Completion criterion: all three artefacts exist and are non-empty; the hash file covers every wrapper you will modify.
Three classes, all mandatory:
| Class | Purpose | Example |
|---|---|---|
| Should block | proves the guard works | rm -rf /tmp/x, sudo ..., chmod -R 777 . |
| Negative control | proves no over-blocking | mv --help, chmod --help, launchctl list |
| Known bypass | keeps you honest | absolute path invocation, bash -c '...', interpreter one-liner |
A matrix without negative controls only measures enthusiasm.
Completion criterion: every case has an expected decision (allow / deny), and at least three negative controls exist.
The guard must expose a classification entry point, for example:
guard_classify <bin> <arg>... # prints allow | deny, exit 0
Run the matrix against that entry point. Never run the destructive command to “see what happens”. Classification and execution are separate contracts.
Completion criterion: scripts/matrix_run.py produces a pass/fail line per case, with zero command execution.
guard_main <bin> "$@".chmod only when -R or 777; mv only when the source is in a protected path; osascript only for quit or do shell script.Completion criterion: every wrapper has a corresponding case in the matrix.
A wrapper with a syntax error makes the wrapped command fail silently — worse than no guard. Run the interpreter's syntax check (bash -n, node --check, python -m py_compile) on every modified file before it is reachable.
Completion criterion: syntax check passes on all modified files; a deliberate broken copy is confirmed to fail the check.
Same cases, same classifier contract, after the change. Diff the decisions line by line. Every difference must be explained as either an intended new block or a regression to fix.
Completion criterion: a diff table exists; no negative control changed to deny.
ts, pid, ppid, cwd, bin, argv, decision.GUARD_ALLOW_DESTRUCTIVE=1, whatever the local convention is) as allow with a reason.PATH, direct syscalls.Completion criterion: a sample log line exists; the bypass list is written in the same document as the guarantee.
If the goal is to record outbound actions rather than block them, do not match the whole command string. echo 'git push' and pgrep -f 'git push' will both false-positive.
;, &&, ||, |, newline.sudo, env, and VAR= prefixes.-X POST, --data, -F for HTTP clients; : for rsync).scripts/bypass_scan.py finds the risky invocation forms in a set of files; it is a scanner, not a blocker.