{"_id":"@agentbee/guards","_rev":"2-fce27252f1a96007586626cd65c3312a","name":"@agentbee/guards","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.0":{"name":"@agentbee/guards","version":"0.1.0","keywords":["agentbee","ai","agent","security","human-in-the-loop","prompt-injection","authorization","guardrails"],"license":"Apache-2.0","_id":"@agentbee/guards@0.1.0","maintainers":[{"name":"proofxhq","email":"contact@proofx.co.uk"}],"homepage":"https://agentbee.co.uk","dist":{"shasum":"d58325e32257e1506a81cd41c212ff6c3c27cc60","tarball":"https://registry.npmjs.org/@agentbee/guards/-/guards-0.1.0.tgz","fileCount":18,"integrity":"sha512-iEAuQrYdDJPAdS8e8t+GsOrtn8MDlz3LJIxQkZmGHfeeiVcOvfeyUdgfFAFIy4TMTpaiQ59zms239iGRUCmYtQ==","signatures":[{"sig":"MEUCIDRmqvBxmM0VdRj7Tq1pkgvRXjt4hbiptJrhXQC9UF2GAiEA5vDovwANEniBqSuW14wRTAFEXIudJjXThXhzjnb+r6s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":41077},"main":"index.js","type":"commonjs","exports":{".":"./index.js","./payments":"./payments-guard.js","./iam-access":"./iam-access-guard.js","./send-as-me":"./send-as-me-guard.js","./exfil-egress":"./exfil-egress-guard.js","./supply-chain":"./supply-chain-guard.js","./agent-governance":"./agent-governance-guard.js","./prompt-injection":"./prompt-injection-guard.js"},"gitHead":"96cc2300be8cc167f5924377ed092f00a70b4c8a","scripts":{"test":"node test.js && node test-new.js"},"_npmUser":{"name":"proofxhq","email":"contact@proofx.co.uk"},"_npmVersion":"10.9.4","description":"Pure, tested risk classifiers that decide which AI-agent actions need a human approval on an AgentBee hardware key.","directories":{},"_nodeVersion":"22.22.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/guards_0.1.0_1781038695506_0.9985118221973064","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@agentbee/guards","version":"0.1.2","description":"Pure, tested risk classifiers that decide which AI-agent actions need a human approval on an AgentBee hardware key.","license":"Apache-2.0","type":"commonjs","main":"index.js","exports":{".":"./index.js","./prompt-injection":"./prompt-injection-guard.js","./payments":"./payments-guard.js","./send-as-me":"./send-as-me-guard.js","./exfil-egress":"./exfil-egress-guard.js","./iam-access":"./iam-access-guard.js","./supply-chain":"./supply-chain-guard.js","./agent-governance":"./agent-governance-guard.js","./smart-home":"./smart-home-guard.js","./host-access":"./host-access-guard.js"},"scripts":{"test":"node test.js && node test-new.js"},"keywords":["agentbee","ai","agent","security","human-in-the-loop","prompt-injection","authorization","guardrails"],"homepage":"https://agentbee.co.uk","publishConfig":{"access":"public"},"_id":"@agentbee/guards@0.1.2","gitHead":"0569511488f5ed80db83c39b73fc73d11409df71","_nodeVersion":"22.22.0","_npmVersion":"10.9.4","dist":{"integrity":"sha512-VQNg+tU/DTNal7hBj/ASp/e00e5s6UYGDQhswL4uqTmKrOmRA10oR/N+4YmXJIuqDOym3DciaaYFvSHoRG2gog==","shasum":"8d1bde9db1f1af52324d0aaf7e3762025f1e2f61","tarball":"https://registry.npmjs.org/@agentbee/guards/-/guards-0.1.2.tgz","fileCount":21,"unpackedSize":49818,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD6Z7BzXMKIu8zeUkQcFGmFOk2uPQprb99FNNGU8h5NiQIhAMDlUU/BnWI6qbBl7w2CJCtfP0CtbId0Z2lgTsvy8bIk"}]},"_npmUser":{"name":"proofxhq","email":"contact@proofx.co.uk"},"directories":{},"maintainers":[{"name":"proofxhq","email":"contact@proofx.co.uk"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/guards_0.1.2_1781041607752_0.9925235293495853"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-09T20:58:15.370Z","modified":"2026-06-09T21:46:48.025Z","0.1.0":"2026-06-09T20:58:15.633Z","0.1.2":"2026-06-09T21:46:47.886Z"},"license":"Apache-2.0","homepage":"https://agentbee.co.uk","keywords":["agentbee","ai","agent","security","human-in-the-loop","prompt-injection","authorization","guardrails"],"description":"Pure, tested risk classifiers that decide which AI-agent actions need a human approval on an AgentBee hardware key.","maintainers":[{"name":"proofxhq","email":"contact@proofx.co.uk"}],"readme":"# AgentBee Guards 🐝\n\n[![npm](https://img.shields.io/npm/v/@agentbee/guards.svg)](https://www.npmjs.com/package/@agentbee/guards)\n[![license](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE)\n![tests](https://img.shields.io/badge/tests-70%2F70-2bd496)\n![release](https://img.shields.io/badge/release-signed-f5c400)\n\nA **guard** is the smallest possible AgentBee contribution: one function that looks\nat a tool call and decides whether a human should approve it on the bee, and how\nhard (tap vs hold). Guards are pure, testable, and framework-agnostic - they plug\ninto the Claude skill, the OpenClaw plugin, the MCP server, git hooks, or your own\ncode.\n\n```\nclassify(toolName, args, ctx) -> { tier, label } | null\n                                   null  = not gated, let it run\n                                   L0-L2 = a quick TAP approves\n                                   L3-L4 = a deliberate HOLD approves\n```\n\nWhen a guard returns a tier, the integration calls the gate, the bee shows `label`,\na human decides, and an approved call gets a signed, ledger-logged receipt.\n\n## Available guards\n\n| Guard | What it gates |\n|---|---|\n| `prompt-injection-guard.js` | Side-effecting actions triggered by **external content** (web/email/file/RAG) rather than the user. The prompt-injection backstop. |\n| `payments-guard.js` | Money movement (pay/transfer/trade/checkout/refund), tier graduated by amount. |\n| `send-as-me-guard.js` | Sending/posting/signing **as you** (email, social, DocuSign, reply-all, mass send). |\n| `exfil-egress-guard.js` | Data leaving or being exposed (secret reads, PII export, make-public, external upload). |\n| `iam-access-guard.js` | Identity/access changes (grant admin, create key, disable MFA, open firewall, approve JIT). |\n| `supply-chain-guard.js` | Publishing artifacts the world pulls (`npm publish`, PyPI, container push, releases). |\n| `agent-governance-guard.js` | Agent meta-actions (spawn sub-agent, self-escalate, agent-to-agent pay, exceed budget). |\n| `smart-home-guard.js` | Physical/IoT actions (unlock door, disarm alarm, open garage, start vehicle, move robot, disable camera). |\n| `host-access-guard.js` | Local-system control (sudo, rm -rf, pipe-to-shell, read SSH/cloud creds, disable security, install daemons, AppleScript, modify system files). |\n\nRun the tests: **`npm test`** (70/70, CI-checked on every push). Each guard ships with\nbenign cases proving it does **not** gate safe actions.\n\n## Use a guard in your agent (3 ways)\n\nImport the runner once; it composes every guard (first match wins):\n\n```js\nconst { decide } = require(\"./index.js\");\nconst d = decide(toolName, args, ctx);   // -> { tier, label, guard } | null\n```\n\n**1. Deterministic (recommended) — a tool-call hook.** The guard decides, not the\nmodel, so it cannot be skipped. See [`example-hook.js`](./example-hook.js):\n\n```js\nconst d = decide(name, args, ctx);\nif (d) execFileSync(\"python3\", [GATE, d.label, scope, d.tier]); // bee must be pressed; fail-closed\n```\n\nWire that into OpenClaw `before_tool_call`, Claude `PreToolUse`, an OpenAI Agents\ntool wrapper, or a git/CI step. Choose guards with\n`decide(name, args, ctx, { use: [\"iam-access\", \"payments\"] })`.\n\n**2. SDK call in your own code.** Before the risky step:\n`if (decide(name, args)) await bee.approve({...})`.\n\n**3. Cooperative (plain English).** With the MCP `request_approval` tool added, just\ntell the agent which classes to gate: *\"Gate IAM changes, payments, and anything\ntriggered by external content with AgentBee.\"* This is softer — the model chooses to\ncall it — so use mode 1 when you need it actually enforced.\n\n> The prompt-injection guard needs `ctx.provenance` (`\"web\"`/`\"email\"`/`\"user\"`/…).\n> If you do not supply it, that guard abstains and the others still gate dangerous\n> actions on their own.\n\n## Write your own guard (the template)\n\nCopy this, change the matcher, add tests, open a PR.\n\n```js\n\"use strict\";\n// AgentBee Guard: <what it protects>.\nconst RISKY = /\\b(your|keywords|here)\\b/;\n\nfunction classify(toolName, args, ctx = {}) {\n  const s = (String(toolName) + \" \" + JSON.stringify(args || {}))\n    .toLowerCase().replace(/[_\\-.]/g, \" \"); // normalise snake_case / kebab / dotted\n  if (!RISKY.test(s)) return null;          // not my concern -> let other guards decide\n  return { tier: \"L4\", label: \"Short human-readable action\" };\n}\n\nmodule.exports = { classify };\n```\n\n### Rules for a good guard\n- **Fail safe.** If you are unsure of the risk, return `L4` (hold), never `null`.\n- **Be specific.** A guard should own one class of danger, not everything.\n- **Label for a human.** `label` is what shows on the 1.47\" screen and gets signed\n  into the receipt - keep it short, plain, and truthful (it must match what runs).\n- **Normalise names.** Tool names come as `db_drop_table`, `db.drop`, `db-drop` -\n  replace `[_\\-.]` with spaces before matching.\n- **Pure + tested.** No I/O in `classify`. Add cases to `test.js`. PRs need green tests.\n- **Never downgrade a destructive action below L3** without an explicit opt-in.\n\n### Then wire it in\nAny integration can chain guards - first non-null wins:\n\n```js\nconst guards = [require(\"./prompt-injection-guard\").classify,\n                require(\"./payments-guard\").classify,\n                require(\"./your-guard\").classify];\nfunction decide(name, args, ctx) {\n  for (const g of guards) { const r = g(name, args, ctx); if (r) return r; }\n  return null;\n}\n```\n\n## License & signature\n\nApache-2.0 (see `LICENSE`). Every release is **signed** with the AgentBee release\nkey (HSM-held); verify it with [`SIGNING.md`](./SIGNING.md). Built by CyberSecAI Ltd.\nContributions welcome under the same license.\n","readmeFilename":"README.md"}