global-agent-guardrails
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseGlobal Agent Guardrails
全局Agent防护机制
A "bouncer" that blocks catastrophic shell commands before any AI agent runs them. One patterns file is the single source of truth; every agent reads it via a shared hook script or a tiny native adapter. It is a seatbelt against accidents, NOT a sandbox against a malicious agent (obfuscation like can slip past regex).
python -c "shutil.rmtree(...)"这是一个“守门人”,能在任何AI Agent执行命令前拦截灾难性Shell命令。一份规则文件是唯一的可信数据源;所有Agent通过共享钩子脚本或轻量原生适配器读取它。它是防止意外的“安全带”,而非针对恶意Agent的沙箱(像这类混淆写法可以绕过正则检测)。
python -c "shutil.rmtree(...)"File map
文件结构
~/.agents/hooks/dangerous-patterns.txt # THE denylist: one POSIX-ERE regex per line, # comments
~/.agents/hooks/deny-dangerous.sh # shared guard: hook JSON on stdin -> exit 2 blocks
~/.agents/hooks/test-guard.sh # test suite: run after ANY pattern change
~/.config/opencode/plugins/command-guard.ts # OpenCode adapter (throws to block)
~/.pi/agent/extensions/command-guard.ts # Pi adapter (returns {block:true})
~/.hermes/plugins/command-guard/ # Hermes plugin (returns {"action":"block"})~/.agents/hooks/dangerous-patterns.txt # 黑名单:每行一个POSIX-ERE正则,#开头为注释
~/.agents/hooks/deny-dangerous.sh # 共享防护脚本:从标准输入读取JSON,返回码2表示拦截
~/.agents/hooks/test-guard.sh # 测试套件:任何规则变更后都需运行
~/.config/opencode/plugins/command-guard.ts # OpenCode适配器(抛出异常实现拦截)
~/.pi/agent/extensions/command-guard.ts # Pi适配器(返回{block:true})
~/.hermes/plugins/command-guard/ # Hermes插件(返回{"action":"block"})State check (is it installed?)
状态检查(是否已安装?)
bash
ls ~/.agents/hooks/deny-dangerous.sh ~/.agents/hooks/dangerous-patterns.txt
~/.agents/hooks/test-guard.sh # must end "failed: 0"If missing, rebuild from the wiring table below.
bash
ls ~/.agents/hooks/deny-dangerous.sh ~/.agents/hooks/dangerous-patterns.txt
~/.agents/hooks/test-guard.sh # 必须以"failed: 0"结尾如果文件缺失,请根据下方的集成表重新构建。
Add or tune a pattern
添加或调整规则
- Edit . Write POSIX ERE (
~/.agents/hooks/dangerous-patterns.txt). Usegrep -E, never[[:space:]]— adapters auto-convert\sto[:space:]for JS/Python and compile in multiline mode.\s - Add block + allow cases to , then run it. Must pass 100%.
test-guard.sh - Verify the new pattern compiles in the adapter engines:
bash
python3 -c 'import re,pathlib; [re.compile(l.strip().replace("[:space:]",r"\s"),re.M) for l in pathlib.Path.home().joinpath(".agents/hooks/dangerous-patterns.txt").read_text().splitlines() if l.strip() and not l.startswith("#")]; print("ok")'- Changes apply instantly everywhere (all consumers re-read the file per command). Exception: Droid uses its own in
commandBlocklist— mirror the change there manually.~/.factory/settings.json
Design rule: block only irreversible/catastrophic commands (data loss, disk wipe, repo deletion, token exfil). Local-destructive-but-recoverable commands (, , ) stay ALLOWED — over-blocking kills agent usefulness.
git statusgit clean -fdxrm -rf node_modulesPassword managers are also a hard NO (pattern group 10): agents must never use their CLIs (, , , , , outright; with any argument at command position; with its real subcommands — bare / stay unblocked because they are common words), dump the macOS keychain (, ), export gpg secret keys, touch vault data (, the bundles), or open/uninstall the apps.
bwbwslpasskeepassxc-clirbwnordpasspassopoppasssecurity find-*-passworddump-keychain~/.password-store.app- 编辑。使用POSIX ERE正则(即
~/.agents/hooks/dangerous-patterns.txt兼容的语法)。使用grep -E表示空格,绝对不要用[[:space:]]——适配器会自动将\s转换为[:space:]以适配JS/Python,并以多行模式编译。\s - 在中添加拦截和允许的测试用例,然后运行脚本。必须100%通过。
test-guard.sh - 验证新规则能在适配器引擎中正常编译:
bash
python3 -c 'import re,pathlib; [re.compile(l.strip().replace("[:space:]",r"\s"),re.M) for l in pathlib.Path.home().joinpath(".agents/hooks/dangerous-patterns.txt").read_text().splitlines() if l.strip() and not l.startswith("#")]; print("ok")'- 变更会立即在所有Agent中生效(所有消费者每次执行命令时都会重新读取规则文件)。例外情况:Droid使用中自带的
~/.factory/settings.json,需手动同步规则变更。commandBlocklist
设计原则:仅拦截不可逆/灾难性命令(数据丢失、磁盘擦除、仓库删除、令牌泄露)。本地破坏性但可恢复的命令(如、、)保持允许——过度拦截会降低Agent的实用性。
git statusgit clean -fdxrm -rf node_modules密码管理器同样是严格禁止的(规则组10):Agent绝不能使用它们的CLI(直接拦截、、、、、;拦截带任意参数的命令;拦截带真实子命令的——仅输入/则不拦截,因为它们是常用词汇),禁止导出macOS钥匙串(、)、导出GPG私钥、触碰密码库数据(、相关包),或打开/卸载这些应用。
bwbwslpasskeepassxc-clirbwnordpasspassopoppasssecurity find-*-passworddump-keychain~/.password-store.appPer-agent wiring (user-global)
按Agent集成(全局用户级)
| Agent | Config | Event | Blocks via |
|---|---|---|---|
| Claude Code | | | shared script, exit 2 |
| Codex CLI/app/IDE | | | shared script, exit 2 |
| Cursor IDE + CLI | | | shared script with |
| Grok (xAI) | auto-loads Claude + Cursor hook files (compat on by default); native option | | shared script (reads |
| OpenCode | | | adapter throws Error |
| Pi | | | adapter returns |
| Hermes | | | plugin returns |
| Droid (Factory) | | native | hard-block, no approval possible |
| Devin CLI | | | shared script, exit 2 |
Hook entry shape for Claude/Codex/Devin (merge into existing object, never overwrite):
hooksjson
{"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "/ABSOLUTE/HOME/.agents/hooks/deny-dangerous.sh"}]}]}}Cursor entry (payload has , so pass the arg):
.commandcursorjson
{"beforeShellExecution": [{"command": "/ABSOLUTE/HOME/.agents/hooks/deny-dangerous.sh cursor", "failClosed": false}]}Use absolute paths in configs ( expansion is inconsistent across agents).
~| Agent | 配置文件 | 触发事件 | 拦截方式 |
|---|---|---|---|
| Claude Code | | | 共享脚本,返回码2 |
| Codex CLI/app/IDE | | | 共享脚本,返回码2 |
| Cursor IDE + CLI | | | 带 |
| Grok (xAI) | 自动加载Claude + Cursor钩子文件(默认兼容开启);原生配置选项 | | 共享脚本(读取 |
| OpenCode | | | 适配器抛出Error |
| Pi | | | 适配器返回 |
| Hermes | | | 插件返回 |
| Droid (Factory) | | 原生 | 强制拦截,无审批可能 |
| Devin CLI | | | 共享脚本,返回码2 |
Claude/Codex/Devin的钩子配置格式(合并到现有对象中,请勿覆盖):
hooksjson
{"hooks": {"PreToolUse": [{"matcher": "Bash", "hooks": [{"type": "command", "command": "/ABSOLUTE/HOME/.agents/hooks/deny-dangerous.sh"}]}]}}Cursor的配置项(负载包含,需传入参数):
.commandcursorjson
{"beforeShellExecution": [{"command": "/ABSOLUTE/HOME/.agents/hooks/deny-dangerous.sh cursor", "failClosed": false}]}配置中请使用绝对路径(不同Agent对的解析行为不一致)。
~Gotchas (hard-won — do not rediscover)
注意事项(经验总结——请勿重复踩坑)
- Codex trust is hash-pinned. Any edit to the hook ENTRY in (not the patterns file) invalidates trust; run
hooks.jsonin Codex and re-trust, else Codex silently skips the guard. Trust hashes live in/hooksin[hooks.state]and are shared by CLI, desktop app, and IDE extension. CI/scripts:~/.codex/config.toml.--dangerously-bypass-hook-trust - Cursor must stay
failClosed. Cursor background/worker hosts cannot execute hook scripts; fail-closed blocks EVERY command there. Trade-off: Cursor background agents run unguarded.false - Hermes plugin manifest key is (not
provides_hooks). Plugin must be enabled:hookslist inplugins.enabled(the~/.hermes/config.yamlCLI prompts interactively and hangs non-interactive shells). Hermes hooks are fail-open on exceptions — keep the plugin trivial. Shell tool name ishermes plugins enable.terminal - Pi handler errors block the tool (fail-safe) — adapter must catch its own errors and fail open, or a broken patterns file bricks every bash call.
tool_call - Droid semantics: = ask for confirmation;
commandDenylist= never runs, even at full autonomy withcommandBlocklist. Use blocklist for catastrophic entries.--skip-permissions-unsafe - Guard script payload detection: command lives at (Claude/Codex/Devin),
.tool_input.command(Grok),.toolInput.command(Cursor). Keep all three in the jq fallback chain..command - Adapter regexes require multiline mode. Keep JavaScript's flag and Python's
msore.Mmatches each shell line like^.grep - False-positive class: a harmless command whose ARGUMENT text contains a dangerous-looking string (e.g. passing a prompt mentioning on a CLI) gets blocked. Workaround: put the text in a file and reference it.
git push --force - Not coverable natively (no hook system as of 2026-07): Gemini CLI, Qwen Code, Amp, kimi-cli. Codex cloud tasks and Cursor background agents also bypass the local guard.
- Codex信任基于哈希固定:对中的钩子配置项(而非规则文件)的任何修改都会使信任失效;需在Codex中运行
hooks.json命令重新信任,否则Codex会静默跳过防护。信任哈希存储在/hooks的~/.codex/config.toml中,CLI、桌面应用和IDE扩展共享该哈希。CI/脚本场景可使用[hooks.state]参数。--dangerously-bypass-hook-trust - Cursor的必须设为
failClosed:Cursor后台/工作进程无法执行钩子脚本;若设为fail-closed会拦截所有后台命令。权衡方案:Cursor后台Agent不启用防护。false - Hermes插件清单的关键字是(而非
provides_hooks)。插件必须启用:在hooks的~/.hermes/config.yaml列表中添加(plugins.enabled命令会交互式提示,在非交互式Shell中会挂起)。Hermes钩子在异常时会fail-open——请保持插件逻辑简洁。Shell工具名称为hermes plugins enable。terminal - Pi的处理器错误会拦截工具(故障安全机制)——适配器必须捕获自身错误并fail-open,否则损坏的规则文件会导致所有bash调用失效。
tool_call - Droid语义说明:= 需确认后执行;
commandDenylist= 绝对不执行,即使在完全自主模式下使用commandBlocklist也无法执行。灾难性命令需加入blocklist。--skip-permissions-unsafe - 防护脚本的负载检测:命令的位置为(Claude/Codex/Devin)、
.tool_input.command(Grok)、.toolInput.command(Cursor)。请在jq回退链中保留这三种路径。.command - 适配器正则需启用多行模式:保留JavaScript的标志和Python的
m,使re.M能匹配Shell的每一行(与^行为一致)。grep - 误拦截场景:无害命令的参数中包含危险字符串(例如在CLI中传入包含的提示文本)会被拦截。解决方法:将文本存入文件后引用。
git push --force - 原生不支持防护(截至2026-07无钩子系统):Gemini CLI、Qwen Code、Amp、kimi-cli。Codex云任务和Cursor后台Agent也会绕过本地防护。
E2E verification recipe
端到端验证方法
Safe probe: ask the agent to run from a NON-git directory — blocked = guard works; "not a git repository" = guard failed but no harm done.
git push --forcebash
cd "$(mktemp -d)"
claude -p 'Run exactly: git push --force. Report the result in one line.' --permission-mode bypassPermissions
codex exec --skip-git-repo-check 'Run exactly: git push --force. Report the result in one line.' < /dev/null
droid exec --auto high -f prompt.txt # prompt text in a file (see false-positive gotcha)
pi -p --no-session 'Run exactly: git push --force. Report the result in one line.'
hermes chat --query 'Run exactly this terminal command: git push --force. Report in one line.'Direct script test without any agent:
bash
echo '{"tool_input":{"command":"rm -rf /"}}' | ~/.agents/hooks/deny-dangerous.sh; echo "exit=$?" # expect exit=2安全测试:让Agent在非Git目录下执行——被拦截=防护生效;提示“not a git repository”=防护失效但无危害。
git push --forcebash
cd "$(mktemp -d)"
claude -p 'Run exactly: git push --force. Report the result in one line.' --permission-mode bypassPermissions
codex exec --skip-git-repo-check 'Run exactly: git push --force. Report the result in one line.' < /dev/null
droid exec --auto high -f prompt.txt # 提示文本存入文件(参考误拦截注意事项)
pi -p --no-session 'Run exactly: git push --force. Report the result in one line.'
hermes chat --query 'Run exactly this terminal command: git push --force. Report in one line.'无需Agent的直接脚本测试:
bash
echo '{"tool_input":{"command":"rm -rf /"}}' | ~/.agents/hooks/deny-dangerous.sh; echo "exit=$?" # 预期返回exit=2