AI agents act — they delete files, push code, drop tables, spend money. This is the layer that judges each action before it runs and answers one question: allow, confirm, or deny?
Runs in production on the author's own agent · v0.1.0
Platforms ship two things that look like policy — and neither can express the sentence that actually matters.
They can block the exec tool. They cannot allow pytest while blocking git push --force — both are the same tool.
A single mode applies to every command equally. It has no way to say “this one is fine, that one is not”.
Config-drift auditors tell you what changed after the fact. Useful — but they are not an enforcement point.
“Confirm the force-push, deny the recursive wipe, and let the test suite run silently.” That needs the command text, judged per call.
Every rule is compiled into the classifier and unit-tested. Deny is for catastrophic; confirm is for genuinely risky but sometimes legitimate.
| Protected | Fires when | Decision |
|---|---|---|
| Filesystem root | rm -rf / or rm -rf /* | deny |
| System directories | whole-tree wipe of /etc /root /var /usr /bin /boot … | deny |
| Secrets & keys | secrets*, any *.env, .ssh/, *-key.pem, private keys | deny |
| Runtime config & state | openclaw.json, credentials, state, secret-egress proxy | deny |
| Secret read-back | reading a stored secret value back out | deny |
| The guard itself | disable / remove / re-consent, config writes, policy reset | deny |
| System paths | writing into /etc /usr /bin /sbin /lib /boot … | deny |
| Destructive delete | any other rm (bounded cleanup is logged instead) | confirm |
| Destructive git | force-push, reset, clean -fd, branch -D, checkout -- . | confirm |
| Database drop | DROP TABLE/DATABASE, dropdb, pg_restore --clean | confirm |
| Spend ceiling | any transaction at or above $500 — never session-trusted | confirm |
| Outside-workspace writes | write, copy or move outside the allowed roots | confirm |
| Outbound messages | every send from the agent | allow-log |
| Allowlisted APIs | network calls to pre-approved hosts only | allow-log |
| Ordinary work | tests, linters, type-checks, builds | allow |
Full rule-by-rule reference ships with the plugin as POLICY.md.
A single before_tool_call hook sees every tool call — the command, the paths, the parameters — before anything executes.
.. and ~ before matchingNo imports, no Gateway, no state. That is deliberate: it makes the rules inspectable and testable without a live call — and it is why the whole rule set can be proven by a test suite.
| Suite | Proves | Result |
|---|---|---|
| classifier | decision logic per rule | 236 passed |
| hook | the real handler blocks / confirms / allows | 21 passed |
| session trust | trust is bounded to one class | 27 passed |
0 failures · runnable with no Gateway
One JSON line per tool call — valid JSONL, safe to ship to a log pipeline. Logging failures never block a call: governance must not fail closed on a write error.
{"ts":"2026-09-18T17:26:50.615Z",
"product":"nibvok",
"action":"deny",
"tool":"exec",
"reason":"read of protected secret material",
"cmd":"cat /root/.openclaw/openclaw.json"}
A guard that overstates itself is worse than none. These are the real limits.
$(…) substitution. A sufficiently creative command can evade a pattern.The plugin is free under MIT-0 — use, modify, and redistribute it with no attribution requirement. For teams that want policies tuned to their environment, audit trails reviewed, or incident response, the author offers paid advisory engagements.
NIBVOK AI Security is part of NIBVOK · [email protected]