@aporthq/aport-agent-guardrails 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. package/LICENSE +217 -0
  2. package/README.md +481 -0
  3. package/bin/agent-guardrails +133 -0
  4. package/bin/aport-create-passport.sh +444 -0
  5. package/bin/aport-cursor-hook.sh +90 -0
  6. package/bin/aport-guardrail-api.sh +108 -0
  7. package/bin/aport-guardrail-bash.sh +394 -0
  8. package/bin/aport-guardrail-v2.sh +5 -0
  9. package/bin/aport-guardrail.sh +5 -0
  10. package/bin/aport-resolve-paths.sh +71 -0
  11. package/bin/aport-status.sh +276 -0
  12. package/bin/frameworks/crewai.sh +49 -0
  13. package/bin/frameworks/cursor.sh +95 -0
  14. package/bin/frameworks/langchain.sh +48 -0
  15. package/bin/frameworks/n8n.sh +36 -0
  16. package/bin/frameworks/openclaw.sh +19 -0
  17. package/bin/lib/allowlist.sh +18 -0
  18. package/bin/lib/common.sh +28 -0
  19. package/bin/lib/config.sh +46 -0
  20. package/bin/lib/constants.sh +232 -0
  21. package/bin/lib/detect.sh +65 -0
  22. package/bin/lib/error.sh +269 -0
  23. package/bin/lib/passport.sh +19 -0
  24. package/bin/lib/templates/.gitkeep +1 -0
  25. package/bin/lib/templates/config.yaml +6 -0
  26. package/bin/lib/validation.sh +206 -0
  27. package/bin/openclaw +660 -0
  28. package/docs/ADDING_A_FRAMEWORK.md +87 -0
  29. package/docs/AGENTS.md.example +40 -0
  30. package/docs/CODE_REVIEW.md +192 -0
  31. package/docs/DEPLOYMENT_READINESS.md +81 -0
  32. package/docs/FAQ_SECURITY_SCANNERS.md +373 -0
  33. package/docs/FRAMEWORK_ROADMAP.md +41 -0
  34. package/docs/HOSTED_PASSPORT_SETUP.md +362 -0
  35. package/docs/IMPLEMENTING_YOUR_OWN_EVALUATOR.md +433 -0
  36. package/docs/OPENCLAW_COMPATIBILITY.md +73 -0
  37. package/docs/OPENCLAW_LOCAL_INTEGRATION.md +596 -0
  38. package/docs/OPENCLAW_TOOLS_AND_POLICIES.md +54 -0
  39. package/docs/QUICKSTART.md +470 -0
  40. package/docs/QUICKSTART_OPENCLAW_PLUGIN.md +470 -0
  41. package/docs/README.md +28 -0
  42. package/docs/RELEASE.md +87 -0
  43. package/docs/REPO_LAYOUT.md +47 -0
  44. package/docs/SKILLS_ECOSYSTEM_ANALYSIS_FEB17.md +1260 -0
  45. package/docs/TOOL_POLICY_MAPPING.md +46 -0
  46. package/docs/UPGRADE.md +46 -0
  47. package/docs/VERIFICATION_METHODS.md +97 -0
  48. package/docs/assets/README.md +8 -0
  49. package/docs/assets/porter.svg +54 -0
  50. package/docs/development/ERROR_CODES.md +616 -0
  51. package/docs/frameworks/GITHUB_ISSUE_PROPOSALS.md +1105 -0
  52. package/docs/frameworks/crewai.md +114 -0
  53. package/docs/frameworks/cursor.md +159 -0
  54. package/docs/frameworks/langchain.md +72 -0
  55. package/docs/frameworks/n8n.md +40 -0
  56. package/docs/frameworks/openclaw.md +40 -0
  57. package/docs/launch/ADD_APORT_AWESOME_LISTS_INSTRUCTIONS.md +146 -0
  58. package/docs/launch/ANNOUNCEMENT_GUIDE.md +266 -0
  59. package/docs/launch/AWESOME_REPOS.md +53 -0
  60. package/docs/launch/CURSOR_VSCODE_HOOKS_RESEARCH.md +77 -0
  61. package/docs/launch/DEMO_TERMINAL_OUTPUT.txt +48 -0
  62. package/docs/launch/DRY_AND_PLAN_CHECKLIST.md +47 -0
  63. package/docs/launch/EVIDENCE_README.md +61 -0
  64. package/docs/launch/EVIDENCE_TERMINAL_CAPTURE.txt +10 -0
  65. package/docs/launch/FRAMEWORK_SUPPORT_PLAN.md +1640 -0
  66. package/docs/launch/LAUNCH_READINESS_CHECKLIST.md +237 -0
  67. package/docs/launch/LAUNCH_STRATEGY_SUMMARY.md +464 -0
  68. package/docs/launch/OPENCLAW_FEEDBACK_AND_FIXES.md +85 -0
  69. package/docs/launch/POST_1_VALENTINE_IMPROVED.md +233 -0
  70. package/docs/launch/POST_2_GUARDRAIL_IMPROVED.md +369 -0
  71. package/docs/launch/PRE_LAUNCH_FIXES.md +766 -0
  72. package/docs/launch/QUICK_LAUNCH_CHECKLIST.md +400 -0
  73. package/docs/launch/READINESS_SUMMARY.md +262 -0
  74. package/docs/launch/README.md +68 -0
  75. package/docs/launch/USER_STORIES.md +327 -0
  76. package/docs/launch/scripts/add-aport-awesome-pr.sh +69 -0
  77. package/docs/operations/MONITORING.md +588 -0
  78. package/docs/reviews/2026-02-18-staff-review.md +268 -0
  79. package/extensions/openclaw-aport/README.md +415 -0
  80. package/extensions/openclaw-aport/index.js +625 -0
  81. package/extensions/openclaw-aport/openclaw-aport.js +7 -0
  82. package/extensions/openclaw-aport/openclaw.plugin.json +46 -0
  83. package/extensions/openclaw-aport/package.json +36 -0
  84. package/extensions/openclaw-aport/test.js +307 -0
  85. package/external/aport-policies/README.md +363 -0
  86. package/external/aport-policies/agent.session.create.v1/README.md +345 -0
  87. package/external/aport-policies/agent.session.create.v1/policy.json +162 -0
  88. package/external/aport-policies/agent.tool.register.v1/README.md +361 -0
  89. package/external/aport-policies/agent.tool.register.v1/policy.json +172 -0
  90. package/external/aport-policies/code.release.publish.v1/README.md +51 -0
  91. package/external/aport-policies/code.release.publish.v1/policy.json +121 -0
  92. package/external/aport-policies/code.repository.merge.v1/README.md +287 -0
  93. package/external/aport-policies/code.repository.merge.v1/express.example.js +332 -0
  94. package/external/aport-policies/code.repository.merge.v1/fastapi.example.py +370 -0
  95. package/external/aport-policies/code.repository.merge.v1/policy.json +162 -0
  96. package/external/aport-policies/data.export.create.v1/README.md +226 -0
  97. package/external/aport-policies/data.export.create.v1/express.example.js +172 -0
  98. package/external/aport-policies/data.export.create.v1/fastapi.example.py +165 -0
  99. package/external/aport-policies/data.export.create.v1/policy.json +133 -0
  100. package/external/aport-policies/data.report.ingest.v1/README.md +134 -0
  101. package/external/aport-policies/data.report.ingest.v1/express.example.js +105 -0
  102. package/external/aport-policies/data.report.ingest.v1/minimal-example.js +68 -0
  103. package/external/aport-policies/data.report.ingest.v1/policy.json +174 -0
  104. package/external/aport-policies/finance.crypto.trade.v1/README.md +146 -0
  105. package/external/aport-policies/finance.crypto.trade.v1/express.example.js +109 -0
  106. package/external/aport-policies/finance.crypto.trade.v1/minimal-example.js +65 -0
  107. package/external/aport-policies/finance.crypto.trade.v1/policy.json +176 -0
  108. package/external/aport-policies/finance.payment.charge.v1/README.md +326 -0
  109. package/external/aport-policies/finance.payment.charge.v1/express.example.js +250 -0
  110. package/external/aport-policies/finance.payment.charge.v1/fastapi.example.py +227 -0
  111. package/external/aport-policies/finance.payment.charge.v1/minimal-example.js +64 -0
  112. package/external/aport-policies/finance.payment.charge.v1/policy.json +224 -0
  113. package/external/aport-policies/finance.payment.charge.v1/tests/contexts.jsonl +12 -0
  114. package/external/aport-policies/finance.payment.charge.v1/tests/expected.jsonl +12 -0
  115. package/external/aport-policies/finance.payment.charge.v1/tests/passport.instance.json +42 -0
  116. package/external/aport-policies/finance.payment.charge.v1/tests/passport.template.json +40 -0
  117. package/external/aport-policies/finance.payment.charge.v1/tests/payments-charge-policy.test.js +817 -0
  118. package/external/aport-policies/finance.payment.charge.v1/tests/test_payments_charge_policy.py +486 -0
  119. package/external/aport-policies/finance.payment.payout.v1/README.md +78 -0
  120. package/external/aport-policies/finance.payment.payout.v1/policy.json +181 -0
  121. package/external/aport-policies/finance.payment.refund.v1/README.md +275 -0
  122. package/external/aport-policies/finance.payment.refund.v1/express.example.js +167 -0
  123. package/external/aport-policies/finance.payment.refund.v1/fastapi.example.py +136 -0
  124. package/external/aport-policies/finance.payment.refund.v1/minimal-example.js +183 -0
  125. package/external/aport-policies/finance.payment.refund.v1/policy.json +216 -0
  126. package/external/aport-policies/finance.payment.refund.v1/tests/refunds-policy.test.js +924 -0
  127. package/external/aport-policies/finance.payment.refund.v1/tests/test_refunds_policy.py +778 -0
  128. package/external/aport-policies/finance.transaction.execute.v1/README.md +309 -0
  129. package/external/aport-policies/finance.transaction.execute.v1/express.example.js +261 -0
  130. package/external/aport-policies/finance.transaction.execute.v1/fastapi.example.py +231 -0
  131. package/external/aport-policies/finance.transaction.execute.v1/minimal-example.js +78 -0
  132. package/external/aport-policies/finance.transaction.execute.v1/policy.json +189 -0
  133. package/external/aport-policies/finance.transaction.execute.v1/tests/contexts.jsonl +12 -0
  134. package/external/aport-policies/finance.transaction.execute.v1/tests/expected.jsonl +12 -0
  135. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.instance.json +42 -0
  136. package/external/aport-policies/finance.transaction.execute.v1/tests/passport.template.json +42 -0
  137. package/external/aport-policies/finance.transaction.execute.v1/tests/test_transactions_policy.py +214 -0
  138. package/external/aport-policies/finance.transaction.execute.v1/tests/transactions-policy.test.js +306 -0
  139. package/external/aport-policies/governance.data.access.v1/README.md +292 -0
  140. package/external/aport-policies/governance.data.access.v1/express.example.js +321 -0
  141. package/external/aport-policies/governance.data.access.v1/fastapi.example.py +279 -0
  142. package/external/aport-policies/governance.data.access.v1/minimal-example.js +65 -0
  143. package/external/aport-policies/governance.data.access.v1/policy.json +208 -0
  144. package/external/aport-policies/governance.data.access.v1/tests/contexts.jsonl +12 -0
  145. package/external/aport-policies/governance.data.access.v1/tests/data-access-policy.test.js +308 -0
  146. package/external/aport-policies/governance.data.access.v1/tests/expected.jsonl +12 -0
  147. package/external/aport-policies/governance.data.access.v1/tests/passport.instance.json +56 -0
  148. package/external/aport-policies/governance.data.access.v1/tests/passport.template.json +56 -0
  149. package/external/aport-policies/governance.data.access.v1/tests/test_data_access_policy.py +214 -0
  150. package/external/aport-policies/legal.contract.review.v1/README.md +109 -0
  151. package/external/aport-policies/legal.contract.review.v1/policy.json +378 -0
  152. package/external/aport-policies/legal.contract.review.v1/tests/legal-contract-review-policy.test.js +609 -0
  153. package/external/aport-policies/legal.contract.review.v1/tests/passport.template.json +49 -0
  154. package/external/aport-policies/mcp.tool.execute.v1/README.md +301 -0
  155. package/external/aport-policies/mcp.tool.execute.v1/policy.json +141 -0
  156. package/external/aport-policies/messaging.message.send.v1/README.md +230 -0
  157. package/external/aport-policies/messaging.message.send.v1/express.example.js +183 -0
  158. package/external/aport-policies/messaging.message.send.v1/fastapi.example.py +193 -0
  159. package/external/aport-policies/messaging.message.send.v1/policy.json +144 -0
  160. package/external/aport-policies/policy-template.json +107 -0
  161. package/external/aport-policies/system.command.execute.v1/README.md +275 -0
  162. package/external/aport-policies/system.command.execute.v1/policy.json +146 -0
  163. package/external/aport-spec/CONTRIBUTING.md +273 -0
  164. package/external/aport-spec/LICENSE +21 -0
  165. package/external/aport-spec/README.md +168 -0
  166. package/external/aport-spec/conformance/README.md +294 -0
  167. package/external/aport-spec/conformance/cases/data.export.v1/contexts/allow_users.json +6 -0
  168. package/external/aport-spec/conformance/cases/data.export.v1/contexts/deny_pii.json +6 -0
  169. package/external/aport-spec/conformance/cases/data.export.v1/expected/allow_users.decision.json +19 -0
  170. package/external/aport-spec/conformance/cases/data.export.v1/expected/deny_pii.decision.json +19 -0
  171. package/external/aport-spec/conformance/cases/data.export.v1/passports/template.json +29 -0
  172. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/allow_50usd.json +9 -0
  173. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_150usd.json +9 -0
  174. package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_currency.json +9 -0
  175. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/allow_50usd.decision.json +19 -0
  176. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_150usd.decision.json +19 -0
  177. package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_currency.decision.json +19 -0
  178. package/external/aport-spec/conformance/cases/payments.refunds.v1/passports/template.json +42 -0
  179. package/external/aport-spec/conformance/package.json +44 -0
  180. package/external/aport-spec/conformance/pnpm-lock.yaml +642 -0
  181. package/external/aport-spec/conformance/src/cases.ts +371 -0
  182. package/external/aport-spec/conformance/src/ed25519.ts +167 -0
  183. package/external/aport-spec/conformance/src/jcs.ts +85 -0
  184. package/external/aport-spec/conformance/src/runner.ts +533 -0
  185. package/external/aport-spec/conformance/src/validators.ts +185 -0
  186. package/external/aport-spec/conformance/test-runner.js +315 -0
  187. package/external/aport-spec/conformance/tsconfig.json +21 -0
  188. package/external/aport-spec/error-schema.json +192 -0
  189. package/external/aport-spec/index.json +12 -0
  190. package/external/aport-spec/integrations/clawmoat/README.md +12 -0
  191. package/external/aport-spec/integrations/shield/README.md +245 -0
  192. package/external/aport-spec/integrations/shield/adapters/index.js +116 -0
  193. package/external/aport-spec/integrations/shield/adapters/system-command-execute.js +133 -0
  194. package/external/aport-spec/integrations/shield/test/README.md +58 -0
  195. package/external/aport-spec/integrations/shield/test/shield.md +40 -0
  196. package/external/aport-spec/integrations/shield/test/test-shield-to-verify.js +274 -0
  197. package/external/aport-spec/metrics-schema.json +504 -0
  198. package/external/aport-spec/oap/CHANGELOG.md +54 -0
  199. package/external/aport-spec/oap/VERSION.md +40 -0
  200. package/external/aport-spec/oap/capability-registry.md +229 -0
  201. package/external/aport-spec/oap/conformance.md +257 -0
  202. package/external/aport-spec/oap/decision-schema.json +114 -0
  203. package/external/aport-spec/oap/examples/context.refund.usd.50.json +9 -0
  204. package/external/aport-spec/oap/examples/decision.allow.sample.json +20 -0
  205. package/external/aport-spec/oap/examples/decision.deny.sample.json +23 -0
  206. package/external/aport-spec/oap/examples/passport.instance.v1.json +50 -0
  207. package/external/aport-spec/oap/examples/passport.template.v1.json +71 -0
  208. package/external/aport-spec/oap/oap-spec.md +426 -0
  209. package/external/aport-spec/oap/passport-schema.json +396 -0
  210. package/external/aport-spec/oap/security.md +213 -0
  211. package/external/aport-spec/oap/vc/context-oap-v1.jsonld +137 -0
  212. package/external/aport-spec/oap/vc/examples/oap-decision-vc.json +37 -0
  213. package/external/aport-spec/oap/vc/examples/oap-passport-vc.json +68 -0
  214. package/external/aport-spec/oap/vc/tools/INTEGRATION.md +375 -0
  215. package/external/aport-spec/oap/vc/tools/README.md +278 -0
  216. package/external/aport-spec/oap/vc/tools/examples/decision-to-vc.js +66 -0
  217. package/external/aport-spec/oap/vc/tools/examples/passport-to-vc.js +83 -0
  218. package/external/aport-spec/oap/vc/tools/examples/vc-to-decision.js +77 -0
  219. package/external/aport-spec/oap/vc/tools/examples/vc-to-passport.js +94 -0
  220. package/external/aport-spec/oap/vc/tools/package.json +38 -0
  221. package/external/aport-spec/oap/vc/tools/pnpm-lock.yaml +472 -0
  222. package/external/aport-spec/oap/vc/tools/src/cli.ts +226 -0
  223. package/external/aport-spec/oap/vc/tools/src/crypto-utils.ts +427 -0
  224. package/external/aport-spec/oap/vc/tools/src/index.ts +653 -0
  225. package/external/aport-spec/oap/vc/tools/src/test.ts +148 -0
  226. package/external/aport-spec/oap/vc/tools/src/vp.ts +382 -0
  227. package/external/aport-spec/oap/vc/tools/test-simple.js +214 -0
  228. package/external/aport-spec/oap/vc/tools/tsconfig.json +19 -0
  229. package/external/aport-spec/oap/vc/vc-mapping.md +443 -0
  230. package/external/aport-spec/passport-schema.json +586 -0
  231. package/external/aport-spec/rate-limiting.md +136 -0
  232. package/external/aport-spec/transport-profile.md +325 -0
  233. package/external/aport-spec/webhook-spec.md +314 -0
  234. package/package.json +70 -0
  235. package/skills/aport-agent-guardrail/SKILL.md +314 -0
  236. package/src/evaluator.js +252 -0
  237. package/src/server/index.js +72 -0
@@ -0,0 +1,266 @@
1
+ # OpenClaw + APort Announcement Guide
2
+
3
+ **Ready to announce OpenClaw is secure!** This guide helps you create announcement materials.
4
+
5
+ ---
6
+
7
+ ## 🎯 Key Messages
8
+
9
+ ### Primary Message
10
+ **"OpenClaw is now secure with APort - Pre-action authorization for commands and MCP tools. One command, no clone required."**
11
+
12
+ ### Supporting Points
13
+ 1. ✅ **One-command setup** - `npx @aporthq/aport-agent-guardrails` (no clone); optional hosted passport via `npx @aporthq/aport-agent-guardrails <agent_id>`
14
+ 2. ✅ **Local-first or API** - Works offline (bash) or with APort API (default in wizard) for full OAP
15
+ 3. ✅ **40+ built-in security patterns** - Protection against injection, path traversal, privilege escalation
16
+ 4. ✅ **4 OpenClaw policies** - Commands, MCP tools, sessions, tool registration
17
+ 5. ✅ **Sub-300ms performance** - Fast enough for real-time agent workflows
18
+
19
+ ---
20
+
21
+ ## 📝 Tweet Draft
22
+
23
+ ```
24
+ 🚀 OpenClaw is now secure with APort!
25
+
26
+ ✅ Pre-action authorization for commands & MCP tools
27
+ ✅ One command: npx @aporthq/aport-agent-guardrails (no clone)
28
+ ✅ 40+ built-in security patterns (injection, path traversal, etc.)
29
+ ✅ 5-minute setup • Hosted passport optional (use your agent_id)
30
+
31
+ 🔗 https://github.com/aporthq/aport-agent-guardrails
32
+ 📖 https://aport.io/openclaw
33
+
34
+ #OpenClaw #AISecurity #PolicyEnforcement
35
+ ```
36
+
37
+ ---
38
+
39
+ ## 📝 Blog Post Outline
40
+
41
+ ### Title
42
+ **"Securing OpenClaw with APort: Pre-Action Authorization in 5 Minutes"**
43
+
44
+ ### Structure
45
+
46
+ 1. **Introduction** (2 paragraphs)
47
+ - OpenClaw's security challenges
48
+ - APort's solution: pre-action authorization
49
+
50
+ 2. **The Problem** (3 paragraphs)
51
+ - TrustClaw addresses runtime security (OAuth, sandboxing)
52
+ - Missing: Pre-action policy enforcement
53
+ - Need for graduated controls (max amounts, daily caps)
54
+
55
+ 3. **The Solution** (4 paragraphs)
56
+ - APort's 4 OpenClaw policies
57
+ - Local-first approach (no cloud dependency)
58
+ - Built-in security patterns
59
+ - Easy integration
60
+
61
+ 4. **Quick Start** (5 paragraphs)
62
+ - One command: `npx @aporthq/aport-agent-guardrails` (no clone); optional `npx @aporthq/aport-agent-guardrails <agent_id>` for hosted passport
63
+ - 5-minute setup guide (wizard installs plugin, passport, smoke test)
64
+ - Code examples and test commands
65
+
66
+ 5. **Security Features** (3 paragraphs)
67
+ - 40+ built-in patterns
68
+ - Cannot be bypassed
69
+ - Defense-in-depth
70
+
71
+ 6. **Performance** (2 paragraphs)
72
+ - Sub-100ms API latency (~60–65 ms mean); local sub-300ms
73
+ - Fast enough for real-time workflows
74
+
75
+ 7. **Next Steps** (2 paragraphs)
76
+ - Try it locally
77
+ - Upgrade to cloud for team features
78
+
79
+ ---
80
+
81
+ ## 🎬 Demo Script
82
+
83
+ ### Video Script (2 minutes)
84
+
85
+ **0:00 - 0:15: Introduction**
86
+ - "OpenClaw is powerful, but needs security"
87
+ - "APort adds pre-action authorization"
88
+ - "Works locally, no cloud required"
89
+
90
+ **0:15 - 0:45: Setup**
91
+ - Run: `npx @aporthq/aport-agent-guardrails` (wizard: config dir, passport choice — hosted or wizard, mode API/local)
92
+ - Show plugin installed; optional: show passport.json or hosted agent_id
93
+
94
+ **0:45 - 1:15: Demo - Command Verification**
95
+ - Show `~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'` (ALLOW)
96
+ - Show `... '{"command":"rm -rf /"}'` (DENY - blocked pattern)
97
+ - Show sudo / dangerous command (DENIED)
98
+
99
+ **1:15 - 1:45: Demo - MCP Tool Verification**
100
+ - Show github.pull_requests.create (ALLOWED)
101
+ - Show evil-server.com (DENIED - server not allowed)
102
+
103
+ **1:45 - 2:00: Wrap-up**
104
+ - "40+ built-in security patterns"
105
+ - "5-minute setup"
106
+ - "Link in description"
107
+
108
+ ---
109
+
110
+ ## 📊 Code Examples for Announcement
111
+
112
+ ### Example 1: Command Verification
113
+
114
+ ```python
115
+ from aport_guardrail import APortGuardrail
116
+
117
+ guardrail = APortGuardrail()
118
+
119
+ # This is ALLOWED
120
+ guardrail.verify_command("npm", ["install"])
121
+
122
+ # This is DENIED (blocked pattern)
123
+ try:
124
+ guardrail.verify_command("rm", ["-rf", "/"])
125
+ except PermissionError:
126
+ print("Dangerous command blocked!")
127
+ ```
128
+
129
+ ### Example 2: MCP Tool Verification
130
+
131
+ ```python
132
+ # This is ALLOWED
133
+ guardrail.verify_mcp_tool(
134
+ "https://mcp.github.com",
135
+ "github.pull_requests.create",
136
+ {"repo": "test/repo"}
137
+ )
138
+
139
+ # This is DENIED (server not allowed)
140
+ try:
141
+ guardrail.verify_mcp_tool(
142
+ "https://evil-server.com",
143
+ "malicious.tool",
144
+ {}
145
+ )
146
+ except PermissionError:
147
+ print("MCP tool blocked!")
148
+ ```
149
+
150
+ ---
151
+
152
+ ## 📈 Performance Metrics
153
+
154
+ ### Key Numbers to Highlight
155
+
156
+ - **P95 Latency**: 268ms (generic evaluators)
157
+ - **Mean Latency**: 178ms
158
+ - **Success Rate**: 100%
159
+ - **Security Patterns**: 40+ built-in patterns
160
+ - **Setup Time**: 5 minutes
161
+ - **Policies**: 4 OpenClaw-specific policies
162
+
163
+ ### Comparison
164
+
165
+ | Metric | Manual Evaluators | Generic Evaluators | Target |
166
+ |--------|------------------|-------------------|--------|
167
+ | P95 Latency | 239ms | 268ms | <200ms |
168
+ | Mean Latency | 165ms | 178ms | <150ms |
169
+ | Success Rate | 100% | 100% | 100% |
170
+
171
+ **Note**: Generic evaluators are 11.8% slower but provide:
172
+ - ✅ Policy-driven (no hardcoded logic)
173
+ - ✅ Easier to maintain
174
+ - ✅ Consistent across all policies
175
+
176
+ ---
177
+
178
+ ## 🎨 Visual Assets
179
+
180
+ ### Screenshot Ideas
181
+
182
+ 1. **Terminal showing verification**
183
+ ```
184
+ ✅ npm install - ALLOWED
185
+ ❌ rm -rf / - DENIED (blocked pattern)
186
+ ❌ sudo apt update - DENIED (not in allowlist)
187
+ ```
188
+
189
+ 2. **Code example showing integration**
190
+ - Python code with APortGuardrail class
191
+ - Clean, readable, well-commented
192
+
193
+ 3. **Architecture diagram**
194
+ - OpenClaw → APort → Policy Evaluation → Allow/Deny
195
+
196
+ ---
197
+
198
+ ## 🔗 Links to Include
199
+
200
+ - **GitHub Repo**: https://github.com/aporthq/aport-agent-guardrails
201
+ - **Integration Guide**: docs/OPENCLAW_LOCAL_INTEGRATION.md
202
+ - **Example Code**: examples/openclaw-integration-example.py
203
+ - **Policy Docs**: policies/system.command.execute.v1/README.md
204
+ - **Website**: https://aport.io
205
+ - **OpenClaw quickstart**: https://aport.io/openclaw (one command: `npx @aporthq/aport-agent-guardrails`)
206
+
207
+ ---
208
+
209
+ ## 📋 Checklist Before Announcement
210
+
211
+ - [ ] Local API server tested and working
212
+ - [ ] Example scripts tested
213
+ - [ ] Documentation reviewed
214
+ - [ ] Performance metrics verified
215
+ - [ ] Security patterns tested
216
+ - [ ] Demo video recorded (optional)
217
+ - [ ] Blog post written (optional)
218
+ - [ ] Social media posts scheduled (optional)
219
+
220
+ ---
221
+
222
+ ## 🚀 Launch Day Checklist
223
+
224
+ - [ ] Post on Twitter/X
225
+ - [ ] Post on LinkedIn
226
+ - [ ] Post on Reddit (r/MachineLearning, r/OpenSource)
227
+ - [ ] Post on Hacker News
228
+ - [ ] Update GitHub README
229
+ - [ ] Send to OpenClaw community
230
+ - [ ] Monitor for questions/feedback
231
+
232
+ ---
233
+
234
+ ## 💬 FAQ for Announcement
235
+
236
+ ### Q: Do I need cloud API?
237
+ **A:** No! Works completely locally. Cloud API is optional for team features.
238
+
239
+ ### Q: How fast is it?
240
+ **A:** Sub-100ms API (P95 ~70 ms); local sub-300ms — fast enough for real-time agent workflows.
241
+
242
+ ### Q: What's protected?
243
+ **A:** Commands, MCP tools, agent sessions, and tool registration. 40+ built-in security patterns.
244
+
245
+ ### Q: Can I bypass the security?
246
+ **A:** No. Built-in security patterns are always enforced, even if you add commands to allowlist.
247
+
248
+ ### Q: How do I upgrade to cloud?
249
+ **A:** Sign up at aport.io, get API key, set environment variables. See docs/UPGRADE_TO_CLOUD.md.
250
+
251
+ ---
252
+
253
+ ## 🎉 Ready to Launch!
254
+
255
+ You have everything you need:
256
+ - ✅ Working implementation
257
+ - ✅ Documentation
258
+ - ✅ Examples
259
+ - ✅ Performance metrics
260
+ - ✅ Security features
261
+
262
+ **Go ahead and announce! 🚀**
263
+
264
+ ---
265
+
266
+ **Made with ❤️ by the APort team**
@@ -0,0 +1,53 @@
1
+ # Awesome Repos: Discovery & Backlinks
2
+
3
+ **Goal:** Get APort Agent Guardrails (or OpenClaw guardrails) listed in curated awesome lists for visibility and SEO. Do **after** guardrail post is live and repo is public.
4
+
5
+ **Suggested timing:** Day 2–3 after launch (once GitHub repo link works and you have a live post to reference).
6
+
7
+ ---
8
+
9
+ ## Repos to Submit To
10
+
11
+ | # | Repo | Focus | Suggested section / placement | Entry idea |
12
+ |---|-----|--------|-------------------------------|------------|
13
+ | 1 | [e2b-dev/awesome-ai-agents](https://github.com/e2b-dev/awesome-ai-agents) | AI autonomous agents list | Security / guardrails or integrations | APort Agent Guardrails — pre-action policy enforcement for OpenClaw |
14
+ | 2 | [Jenqyang/Awesome-AI-Agents](https://github.com/Jenqyang/Awesome-AI-Agents) | Autonomous agents (LLM) | Tools or Security | APort Guardrails — authorization layer for OpenClaw agents |
15
+ | 3 | [VoltAgent/awesome-openclaw-skills](https://github.com/VoltAgent/awesome-openclaw-skills) | OpenClaw skills | **Security & Passwords** (guardrails fit here) | guardrails — Pre-action policy enforcement; blocks dangerous commands, 40+ patterns |
16
+ | 4 | [rohitg00/awesome-openclaw](https://github.com/rohitg00/awesome-openclaw) | OpenClaw resources | Security or Integrations | APort Guardrails — pre-action authorization for OpenClaw |
17
+ | 5 | [hesamsheikh/awesome-openclaw-usecases](https://github.com/hesamsheikh/awesome-openclaw-usecases) | OpenClaw use cases | New category or Infrastructure | Security / guardrails use case |
18
+ | 6 | [SamurAIGPT/awesome-openclaw](https://github.com/SamurAIGPT/awesome-openclaw) | OpenClaw resources, tools, skills | Security or Community Projects | APort Guardrails — deterministic policy enforcement for OpenClaw |
19
+
20
+ ---
21
+
22
+ ## Suggested entry text (copy-paste for PRs)
23
+
24
+ **Short (for most lists):**
25
+ ```markdown
26
+ - [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) — Pre-action guardrails for OpenClaw (`before_tool_call` plugin, 40+ blocked patterns, local or API). Setup: `npx @aporthq/aport-agent-guardrails`
27
+ ```
28
+
29
+ **With one line of detail:**
30
+ ```markdown
31
+ - [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) — Deterministic policy enforcement for OpenClaw (passport + plugin). Allowlist commands, block `rm -rf`, cap messaging; local-first with optional API mode. Setup: `npx @aporthq/aport-agent-guardrails`
32
+ ```
33
+
34
+ ---
35
+
36
+ ## Checklist (use with QUICK_LAUNCH_CHECKLIST)
37
+
38
+ - [ ] e2b-dev/awesome-ai-agents — open PR (check their CONTRIBUTING for format)
39
+ - [ ] Jenqyang/Awesome-AI-Agents — open PR
40
+ - [ ] VoltAgent/awesome-openclaw-skills — open PR (Security & Passwords section)
41
+ - [ ] rohitg00/awesome-openclaw — open PR
42
+ - [ ] hesamsheikh/awesome-openclaw-usecases — open PR or new use case doc
43
+ - [ ] SamurAIGPT/awesome-openclaw — open PR
44
+
45
+ **Note:** Each repo has its own CONTRIBUTING and format. Read the README and existing entries before submitting.
46
+
47
+ ---
48
+
49
+ ## Links (for PR descriptions)
50
+
51
+ - **Repo:** https://github.com/aporthq/aport-agent-guardrails
52
+ - **npm:** https://www.npmjs.com/package/@aporthq/aport-agent-guardrails
53
+ - **QuickStart:** https://github.com/aporthq/aport-agent-guardrails/blob/main/docs/QUICKSTART_OPENCLAW_PLUGIN.md
@@ -0,0 +1,77 @@
1
+ # Cursor vs VS Code: Hooks, Extensions, and ROI
2
+
3
+ **Purpose:** Decide how to support Cursor and VS Code (Copilot) with maximum traction and minimum effort.
4
+
5
+ ---
6
+
7
+ ## 1. Can we use a VS Code extension for “before execution” hooks?
8
+
9
+ **Short answer: No for vanilla VS Code; not needed for Copilot/Cursor.**
10
+
11
+ | Environment | Before shell/tool execution? | How? |
12
+ |-------------|------------------------------|------|
13
+ | **VS Code (no Copilot)** | **No** | The VS Code extension API has no way to intercept terminal commands before they run. `Terminal.onDidWriteData` is after the fact. You cannot build an extension that “hooks before every shell execution” in plain VS Code. |
14
+ | **VS Code + GitHub Copilot (agent)** | **Yes** | Via **agent hooks** (Preview in VS Code 1.109.3+). Hooks are **config-driven**, not extension API–driven: JSON config files point to **shell scripts**. |
15
+ | **Cursor** | **Yes** | Native **hooks** (e.g. `beforeShellExecution`, `preToolUse`). Same idea: config file + script. Cursor can also load **Claude Code** hook config from `~/.claude/settings.json`. |
16
+
17
+ So “before execution” is available only where an **agent** runs (Copilot, Cursor, Claude Code), and in those cases it’s done via **hooks + scripts**, not via a VS Code extension API.
18
+
19
+ ---
20
+
21
+ ## 2. Common thing in the VS Code ecosystem that adds the most value with least effort
22
+
23
+ **Recommendation: One hook script + one installer that writes the right config for each host. No VS Code extension required for the core behavior.**
24
+
25
+ ### Why hooks (script + config) beat an extension here
26
+
27
+ 1. **Same mechanism everywhere**
28
+ - **VS Code (Copilot):** [Agent hooks (Preview)](https://code.visualstudio.com/docs/copilot/customization/hooks) — config in `~/.claude/settings.json`, `.claude/settings.json`, or `.github/hooks/*.json`. `PreToolUse` runs a command (our script).
29
+ - **Cursor:** [Hooks](https://cursor.com/docs/agent/hooks) — config in `~/.cursor/hooks.json` or `.cursor/hooks.json`. `beforeShellExecution` / `preToolUse` run a command.
30
+ - **Claude Code:** `~/.claude/settings.json`, same PreToolUse style.
31
+ All of them: **JSON config → shell script → stdin JSON in, stdout JSON out, exit 2 = block.**
32
+
33
+ 2. **One script, many editors**
34
+ A single APort hook script can:
35
+ - Read JSON from stdin (tool name + input; e.g. `runTerminalCommand` / `command` for shell).
36
+ - Map to our policy (e.g. `system.command.execute.v1`).
37
+ - Call the existing guardrail (bash or API).
38
+ - Emit the host’s expected JSON (e.g. VS Code: `permissionDecision: allow|deny|ask`, Cursor: allow/deny + exit code).
39
+ - Use **exit 2** to block (both Cursor and VS Code use exit 2 for “block”).
40
+
41
+ 3. **Extension adds little for interception**
42
+ - Vanilla VS Code: extension **cannot** intercept shell execution (no API).
43
+ - Copilot/Cursor: interception is already done by **hooks**, not by extensions. An extension would at best **write** the same hook config and maybe add a “Install APort guardrails” command. That’s optional UX; the core value is the **script + config**.
44
+
45
+ ### What to build (high value, low effort)
46
+
47
+ | Deliverable | Effort | Value |
48
+ |-------------|--------|--------|
49
+ | **One hook script** (e.g. `aport-hook.sh`) that parses stdin (Cursor/Copilot/Claude format), calls existing guardrail, returns allow/deny + exit 0/2 | Low | High — works in Cursor, VS Code Copilot, Claude Code |
50
+ | **Installer** (`npx @aporthq/aport-agent-guardrails cursor` or `--framework=cursor`) that runs passport wizard and writes `~/.cursor/hooks.json` (and optionally `~/.claude/settings.json`) pointing at the script | Low | High — one command to enable guardrails |
51
+ | **Docs** for Cursor, VS Code+Copilot, and Claude Code (where to put config, example `PreToolUse` / `beforeShellExecution` snippet) | Low | High — reuse same script everywhere |
52
+ | **VS Code extension** that only writes hook config + “Install guardrails” command | Medium | Low–medium — nicer discoverability, same behavior as script+installer |
53
+
54
+ So the **common thing** that adds the most value with least effort is: **one script + config for PreToolUse / beforeShellExecution**, shared across Cursor, VS Code (Copilot), and Claude Code. A VS Code extension is optional polish, not required for “works in VS Code (Copilot) and other flavours.”
55
+
56
+ ---
57
+
58
+ ## 3. PreToolUse / beforeShellExecution availability
59
+
60
+ | Platform | PreToolUse / beforeShellExecution | Config location |
61
+ |----------|-----------------------------------|------------------|
62
+ | **VS Code (Copilot)** | Yes — `PreToolUse` (Preview) | `~/.claude/settings.json`, `.claude/settings.json`, `.github/hooks/*.json` |
63
+ | **Cursor** | Yes — `preToolUse`, `beforeShellExecution` | `~/.cursor/hooks.json`, `.cursor/hooks.json` |
64
+ | **Claude Code** | Yes — `PreToolUse` | `~/.claude/settings.json`, `.claude/settings.json` |
65
+ | **VS Code (no agent)** | N/A | No agent → no tool/shell interception in the first place |
66
+
67
+ So **PreToolUse / beforeShellExecution is available** exactly where we care: Cursor, VS Code+Copilot, and Claude Code. It’s not available in “plain VS Code” because there’s no agent running tools/shell there.
68
+
69
+ ---
70
+
71
+ ## 4. ROI vs effort: summary
72
+
73
+ - **Implement:** One **hook script** + **installer** that writes the right **hooks config** for Cursor (and optionally for VS Code/Claude via `~/.claude/settings.json`). Document for Cursor, VS Code+Copilot, and Claude Code.
74
+ - **Skip for MVP:** A VS Code extension whose only job is to install guardrails. Same outcome can be achieved with `npx @aporthq/aport-agent-guardrails cursor` (or a `copilot` framework flag) and one script; extension can be added later if we want marketplace discoverability.
75
+ - **Do not rely on:** A VS Code extension to “intercept shell execution” in vanilla VS Code — the API doesn’t support it; interception only exists in agent-based products and is done via hooks.
76
+
77
+ This keeps effort low and ROI high: one script, one installer, one set of docs, and it works on Cursor, VS Code (Copilot), and other flavours that use the same hook format (e.g. Claude Code).
@@ -0,0 +1,48 @@
1
+ # Demo terminal output (for screenshot / evidence)
2
+
3
+ Use this as reference for what to show in the guardrail launch post. The guardrail script itself only exits 0 (ALLOW) or 1 (DENY) and writes JSON to the decision file; it does not print "ALLOW"/"DENY" to the terminal. To get the output below, run the commands and then echo the result (or use the one-liners at the end).
4
+
5
+ ---
6
+
7
+ ## Option A: With decision JSON (full)
8
+
9
+ $ aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
10
+ ✅ ALLOW
11
+ {"allow":true,"assurance_level":"L2","decision_id":"...","policy_id":"system.command.execute.v1","reasons":[{"code":"oap.allowed","message":"All policy checks passed"}],...}
12
+
13
+ $ aport-guardrail.sh system.command.execute '{"command":"rm -rf /"}'
14
+ ❌ DENY
15
+ {"allow":false,...,"reasons":[{"code":"oap.command_not_allowed","message":"Command 'rm -rf /' is not in allowed list"}],...}
16
+
17
+ ---
18
+
19
+ ## Option B: Short (ALLOW/DENY only — best for screenshot)
20
+
21
+ $ aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
22
+ ✅ ALLOW
23
+
24
+ $ aport-guardrail.sh system.command.execute '{"command":"rm -rf /"}'
25
+ ❌ DENY - Blocked pattern: rm -rf /
26
+
27
+ ---
28
+
29
+ ## Commands to run (from repo with fixture passport)
30
+
31
+ # ALLOW
32
+ OPENCLAW_PASSPORT_FILE=tests/fixtures/passport.oap-v1.json ./bin/aport-guardrail-bash.sh system.command.execute '{"command":"mkdir test"}'
33
+ echo "✅ ALLOW (exit $?)"
34
+
35
+ # DENY
36
+ OPENCLAW_PASSPORT_FILE=tests/fixtures/passport.oap-v1.json ./bin/aport-guardrail-bash.sh system.command.execute '{"command":"rm -rf /"}' || true
37
+ echo "❌ DENY (exit 1) - Blocked pattern: rm -rf /"
38
+
39
+ ---
40
+
41
+ ## If using installed ~/.openclaw/.skills/aport-guardrail.sh
42
+
43
+ Ensure ~/.openclaw/.aport-repo points to your repo and ~/.openclaw/passport.json exists. Then:
44
+
45
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"mkdir test"}' && echo '✅ ALLOW' || echo '❌ DENY'
46
+ ~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"rm -rf /"}' && echo '✅ ALLOW' || echo '❌ DENY'
47
+
48
+ Second line will print ❌ DENY (script exits 1).
@@ -0,0 +1,47 @@
1
+ # DRY and FRAMEWORK_SUPPORT_PLAN alignment checklist
2
+
3
+ This doc confirms the codebase follows the structure, conventions, and best practices in [FRAMEWORK_SUPPORT_PLAN.md](FRAMEWORK_SUPPORT_PLAN.md). Use it to keep the repo DRY and aligned with the plan.
4
+
5
+ ## Repository structure (plan vs actual)
6
+
7
+ | Plan | Actual | Status |
8
+ |------|--------|--------|
9
+ | `bin/lib/` common, passport, config, allowlist | `bin/lib/common.sh`, `passport.sh`, `config.sh`, `allowlist.sh`, `detect.sh`, `templates/` | ✅ |
10
+ | `bin/frameworks/<name>.sh` thin scripts | `bin/frameworks/openclaw.sh`, `langchain.sh`, `crewai.sh`, `n8n.sh` (<50 lines each) | ✅ |
11
+ | Shared wizard: `bin/aport-create-passport.sh` | All frameworks use it via `lib/passport.sh` or delegate (OpenClaw) | ✅ |
12
+ | Config locations: OpenClaw `~/.openclaw`, LangChain `~/.aport/langchain/`, etc. | `lib/config.sh` `get_config_dir()` + `write_config_template()` | ✅ |
13
+ | `integrations/<framework>/` | `integrations/openclaw/`, `langchain/`, `crewai/`, `n8n/` (README, examples) | ✅ |
14
+ | `python/aport_guardrails/` core | `core/evaluator.py`, `config.py`, `passport.py`, `exceptions.py` | ✅ |
15
+ | `python/.../langchain` adapter | `langchain_adapter/` + `aport_guardrails_langchain` import package | ✅ |
16
+
17
+ ## Shared vs divergent (DRY)
18
+
19
+ - **Shared (no duplication):** Passport wizard, policy packs (`external/aport-policies`), tool→pack_id mapping (bash, Node, Python share same semantics), config read/write, kill switch = passport status only (no file).
20
+ - **Divergent (per-framework only):** Integration hook (callback vs decorator vs plugin), config file location, CLI entry (`aport-langchain` vs `bin/openclaw`).
21
+
22
+ ## Verification: two passport options, two policy options
23
+
24
+ Per agent-passport API `POST /api/verify/policy/{pack_id}` (see agent-passport `functions/api/verify/policy/[pack_id].ts`):
25
+
26
+ - **Passport:** (1) **agent_id** in context → API fetches passport (cloud). (2) **passport** in body → API uses it directly (local via API).
27
+ - **Policy:** (1) **pack_id** in URL path → policy from registry. (2) **policy** in body when `pack_id=IN_BODY` → policy from request.
28
+
29
+ | Layer | agent_id | passport in body | pack_id in path | policy in body (API) |
30
+ |-------|----------|------------------|-----------------|----------------------|
31
+ | **Node (src/evaluator.js)** | ✅ context.agent_id | ✅ body.passport | ✅ URL | ✅ options.policyInBody → IN_BODY + body.policy |
32
+ | **Bash (aport-guardrail-api.sh)** | ✅ APORT_AGENT_ID | ✅ via Node (passport loaded and passed) | ✅ via Node | N/A (uses Node) |
33
+ | **Python (core/evaluator.py)** | ✅ context.agent_id | ✅ body.passport (from passport_path) | ✅ URL _tool_to_pack_id | ✅ full OAP pack → IN_BODY + body.policy |
34
+
35
+ **Note:** Local verification with policy-in-body (e.g. passing a policy object to the bash guardrail or a future local evaluator) is planned and not implemented yet.
36
+
37
+ ## Test coverage (Story C and general)
38
+
39
+ - **Unit:** `aport_guardrails/frameworks/langchain.py` (LangChainAdapter) — pytest in core or adapter; callback deny → `GuardrailViolation` covered in `langchain_adapter/tests/test_callback.py`.
40
+ - **Integration:** Example under `examples/langchain/` with temp config/passport; ALLOW/DENY flows in `run_with_guardrail.py`.
41
+ - **E2E:** GH Action installs package, `aport-langchain setup --ci`, runs sample agent or example, expects ALLOW log (see `.github/workflows/e2e-langchain.yml` or equivalent).
42
+
43
+ ## Doc references
44
+
45
+ - [FRAMEWORK_SUPPORT_PLAN.md](FRAMEWORK_SUPPORT_PLAN.md) — architecture, shared vs divergent, per-framework patterns.
46
+ - [USER_STORIES.md](USER_STORIES.md) — acceptance criteria and implementation status.
47
+ - [ADDING_A_FRAMEWORK.md](../ADDING_A_FRAMEWORK.md) — how to add a framework without copying passport/config logic.
@@ -0,0 +1,61 @@
1
+ # Launch evidence
2
+
3
+ **Before publishing the guardrail launch post:**
4
+
5
+ 1. **Repo public:** In GitHub repo settings, set the repository to **Public**. Verify https://github.com/aporthq/aport-agent-guardrails does not 404.
6
+
7
+ 2. **Evidence captured:** Terminal ALLOW/DENY transcript is in ** [EVIDENCE_TERMINAL_CAPTURE.txt](EVIDENCE_TERMINAL_CAPTURE.txt)** (guardrail exit 0 = ALLOW, exit 1 = DENY). For the post, use a screenshot of that output—or run the same commands and capture. Save as **`evidence-allow-deny.png`** in this folder if you want a dedicated image. See **`DEMO_TERMINAL_OUTPUT.txt`** for one-liner variants.
8
+
9
+ DENY:
10
+ aport-guardrail.sh system.command.execute '{"command":"rm -rf /"}'
11
+ ❌ DENY
12
+ {
13
+ "allow":false,
14
+ "assurance_level":"L2",
15
+ "decision_id":"A0A4C0DE-D6AB-4F9E-A5ED-7002919C0375",
16
+ "expires_at":"2026-02-16T18:49:22Z",
17
+ "issued_at":"2026-02-16T17:49:22Z",
18
+ "kid":"oap:local:dev-key",
19
+ "owner_id":"user@example.com",
20
+ "passport_digest":"sha256:2c8368260593935ff699b5223d4101458881e3678e9b4ef992ad522bdabe198b",
21
+ "passport_id":"CDE60F4E-49DC-4D97-AC05-190E693C202C",
22
+ "policy_id":"system.command.execute.v1",
23
+ "prev_content_hash":"sha256:8bb0fd773e38bb412fa79e9857392b746d891dde929764ddbaca76235d45b0c8",
24
+ "prev_decision_id":"3E79C583-3A42-413C-830D-DA2480AD25C9",
25
+ "reasons":[
26
+ {
27
+ "code":"oap.command_not_allowed",
28
+ "message":"Command 'rm -rf /' is not in allowed list"
29
+ }
30
+ ],
31
+ "signature":"ed25519:local-unsigned",
32
+ "content_hash":"sha256:5d61ab149eb0e86e1c1d9d5822ba6714eb7b7a6ddc823130595132cd29974270"
33
+ }
34
+
35
+
36
+ ALLOW:
37
+ aport-guardrail.sh system.command.execute '{"command":"mkdir test"}'
38
+ ✅ ALLOW
39
+
40
+ {
41
+ "allow":true,
42
+ "assurance_level":"L2",
43
+ "decision_id":"3E79C583-3A42-413C-830D-DA2480AD25C9",
44
+ "expires_at":"2026-02-16T18:49:18Z",
45
+ "issued_at":"2026-02-16T17:49:18Z",
46
+ "kid":"oap:local:dev-key",
47
+ "owner_id":"user@example.com",
48
+ "passport_digest":"sha256:2c8368260593935ff699b5223d4101458881e3678e9b4ef992ad522bdabe198b",
49
+ "passport_id":"CDE60F4E-49DC-4D97-AC05-190E693C202C",
50
+ "policy_id":"system.command.execute.v1",
51
+ "prev_content_hash":"sha256:9572913a7cc9595629ba07ed8cf91868889987e655d69445d52bdbfc0961b827",
52
+ "prev_decision_id":"A5CA49E4-849D-4ED8-BB68-177F1784726C",
53
+ "reasons":[
54
+ {
55
+ "code":"oap.allowed",
56
+ "message":"All policy checks passed"
57
+ }
58
+ ],
59
+ "signature":"ed25519:local-unsigned",
60
+ "content_hash":"sha256:8bb0fd773e38bb412fa79e9857392b746d891dde929764ddbaca76235d45b0c8"
61
+ }
@@ -0,0 +1,10 @@
1
+ # Actual capture — guardrail ALLOW/DENY (run with fixture passport)
2
+ # Generated: 2026-02-16T19:15:11Z
3
+
4
+ $ OPENCLAW_PASSPORT_FILE=tests/fixtures/passport.oap-v1.json ./bin/aport-guardrail-bash.sh system.command.execute '{"command":"mkdir test"}'
5
+ Exit: 0
6
+ ✅ ALLOW
7
+
8
+ $ OPENCLAW_PASSPORT_FILE=tests/fixtures/passport.oap-v1.json ./bin/aport-guardrail-bash.sh system.command.execute '{"command":"rm -rf /"}'
9
+ Exit: 1
10
+ ❌ DENY - Blocked pattern: rm -rf /