@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,470 @@
1
+ # QuickStart: OpenClaw Plugin (Deterministic Enforcement)
2
+
3
+ **5-minute setup for deterministic, platform-level policy enforcement in OpenClaw.**
4
+
5
+ **One command to get started** (recommended — no clone):
6
+
7
+ ```bash
8
+ npx @aporthq/aport-agent-guardrails
9
+ ```
10
+
11
+ If you already have an agent_id from aport.io (e.g. after creating a passport there), run `npx @aporthq/aport-agent-guardrails <agent_id>` to use a hosted passport and skip the passport prompt. See [Hosted passport setup](HOSTED_PASSPORT_SETUP.md).
12
+
13
+ This uses the [npm package](https://www.npmjs.com/package/@aporthq/aport-agent-guardrails): it downloads the package (policies + plugin), runs the setup wizard, installs the APort OpenClaw plugin, and runs a smoke test.
14
+
15
+ Then start OpenClaw with the generated config (e.g. `openclaw gateway start --config ~/.openclaw/config.yaml`). The plugin will enforce policies on every tool call.
16
+
17
+ **Alternative: clone the repo** (e.g. to hack on the code or use without npm):
18
+
19
+ ```bash
20
+ git clone https://github.com/aporthq/aport-agent-guardrails.git && \
21
+ cd aport-agent-guardrails && \
22
+ git submodule update --init --recursive && \
23
+ ./bin/openclaw
24
+ ```
25
+
26
+ *Already have the repo?* From the repo root run: `./bin/openclaw`
27
+
28
+ ---
29
+
30
+ ## Why Use the Plugin?
31
+
32
+ | Approach | Deterministic? | Bypass Risk | Security Level |
33
+ |----------|----------------|-------------|----------------|
34
+ | **OpenClaw Plugin** ✅ | Yes | None | 🟢 Secure |
35
+ | AGENTS.md prompts | No | High | 🔴 Not secure |
36
+
37
+ **Bottom line:** With the plugin, the platform enforces policy before every tool execution. The AI cannot bypass it.
38
+
39
+ ---
40
+
41
+ ## Installation (Automatic)
42
+
43
+ **Recommended:** Use `npx @aporthq/aport-agent-guardrails` (see top of this doc). If you cloned the repo instead, from the repo root run:
44
+
45
+ ```bash
46
+ ./bin/openclaw
47
+ ```
48
+
49
+ The script will:
50
+ 1. Ask for your OpenClaw config directory (default `~/.openclaw`)
51
+ 2. Create your passport (OAP v1.0) there
52
+ 3. Prompt to install the APort OpenClaw plugin
53
+ 4. Ask for mode (default: **API**; or local) and generate `config.yaml` with plugin settings (passport path, guardrail script path, apiUrl for API mode)
54
+ 5. Install guardrail wrappers in the config dir’s `.skills/` (including `aport-guardrail-bash.sh` used by the plugin in local mode)
55
+ 6. **Update your passport** — the installer sets `allowed_commands: ["*"]` automatically so normal exec works with no manual editing. You only need to edit the passport later if you want to restrict commands more tightly.
56
+ 7. Run a **self-check** (guardrail invoked the same way OpenClaw will use it); if it’s denied, the script exits with a clear message so you know the setup is incomplete.
57
+ 8. Optionally install the APort skill and AGENTS.md rule, and run a smoke test
58
+ 9. Verify plugin installation
59
+
60
+ **That's it!** Start OpenClaw with that config (e.g. `openclaw gateway start --config ~/.openclaw/config.yaml`). The plugin will enforce policies on every tool call; no extra steps required.
61
+
62
+ ---
63
+
64
+ ## Installation (Manual)
65
+
66
+ If you prefer manual installation:
67
+
68
+ ### 1. Create Passport
69
+
70
+ ```bash
71
+ ./bin/aport-create-passport.sh --output ~/.openclaw/aport/passport.json
72
+ ```
73
+
74
+ ### 2. Install Plugin
75
+
76
+ ```bash
77
+ openclaw plugins install /path/to/aport-agent-guardrails/extensions/openclaw-aport
78
+ ```
79
+
80
+ ### 3. Configure Plugin
81
+
82
+ Create or edit `~/.openclaw/config.yaml`:
83
+
84
+ ```yaml
85
+ plugins:
86
+ enabled: true
87
+ entries:
88
+ openclaw-aport:
89
+ enabled: true
90
+ config:
91
+ # Mode: "api" (default, recommended) or "local" (guardrail script, no network)
92
+ mode: api
93
+
94
+ # Passport file location
95
+ passportFile: ~/.openclaw/aport/passport.json
96
+
97
+ # For local mode: path to guardrail script
98
+ guardrailScript: ~/.openclaw/.skills/aport-guardrail-bash.sh
99
+
100
+ # Fail-closed: block on error (default: true)
101
+ failClosed: true
102
+ ```
103
+
104
+ For **API mode (default)**, set:
105
+ ```yaml
106
+ mode: api
107
+ apiUrl: https://api.aport.io
108
+ ```
109
+ Set `APORT_API_KEY` in the environment if your API requires auth. Do not put `${APORT_API_KEY}` in the config file (OpenClaw will require the var to exist at load time).
110
+
111
+ ### 4. Install Guardrail Scripts (local mode only)
112
+
113
+ If you **did not** run `./bin/openclaw`, you need the guardrail script for local mode. If you **did** run the setup script, it already created `CONFIG_DIR/.skills/aport-guardrail-bash.sh`; skip this step.
114
+
115
+ Otherwise:
116
+
117
+ ```bash
118
+ mkdir -p ~/.openclaw/.skills
119
+ # Create wrapper that points to this repo (replace /path/to with real path)
120
+ cat > ~/.openclaw/.skills/aport-guardrail-bash.sh << 'EOF'
121
+ #!/bin/bash
122
+ APORT_REPO_ROOT="/path/to/aport-agent-guardrails"
123
+ export OPENCLAW_PASSPORT_FILE="${OPENCLAW_PASSPORT_FILE:-$HOME/.openclaw/aport/passport.json}"
124
+ export OPENCLAW_DECISION_FILE="${OPENCLAW_DECISION_FILE:-$HOME/.openclaw/aport/decision.json}"
125
+ exec "$APORT_REPO_ROOT/bin/aport-guardrail-bash.sh" "$@"
126
+ EOF
127
+ chmod +x ~/.openclaw/.skills/aport-guardrail-bash.sh
128
+ ```
129
+
130
+ ### 5. Verify Installation
131
+
132
+ ```bash
133
+ # Check plugin is installed
134
+ openclaw plugins list | grep openclaw-aport
135
+
136
+ # Should show: openclaw-aport (enabled)
137
+ ```
138
+
139
+ ---
140
+
141
+ ## How It Works
142
+
143
+ ```
144
+ User → AI: "Delete all log files"
145
+
146
+ OpenClaw: AI wants to use tool "exec.run"
147
+
148
+ Platform: Fires before_tool_call hook
149
+
150
+ APort Plugin: Maps "exec.run" → "system.command.execute.v1"
151
+
152
+ APort Plugin: Calls guardrail script/API
153
+
154
+ Guardrail: Evaluates against passport + limits
155
+
156
+ ┌──────────┴──────────┐
157
+ │ │
158
+ ALLOW DENY
159
+ │ │
160
+ ↓ ↓
161
+ Tool executes Returns { block: true, blockReason }
162
+
163
+ OpenClaw throws error
164
+
165
+ Tool NEVER executes
166
+ ```
167
+
168
+ **Key:** The platform enforces policy. The AI cannot skip this check.
169
+
170
+ ---
171
+
172
+ ## Testing
173
+
174
+ ### 1. Start OpenClaw with Plugin
175
+
176
+ ```bash
177
+ openclaw gateway start --config ~/.openclaw/config.yaml
178
+ ```
179
+
180
+ ### 2. Test Allowed Action
181
+
182
+ Try a simple command that should be allowed:
183
+
184
+ ```bash
185
+ # Via OpenClaw agent
186
+ "Run: node --version"
187
+ ```
188
+
189
+ Expected: Command executes (allowed by passport limits)
190
+
191
+ ### 3. Test Denied Action
192
+
193
+ Try a command that exceeds your passport limits:
194
+
195
+ ```bash
196
+ # Via OpenClaw agent
197
+ "Delete all files in /tmp"
198
+ ```
199
+
200
+ Expected: Tool blocked with message:
201
+ ```
202
+ 🛡️ APort Policy Denied
203
+
204
+ Policy: system.command.execute.v1
205
+ Reason: Command exceeds allowed scope
206
+
207
+ To override, update your passport at: ~/.openclaw/aport/passport.json (or ~/.openclaw/passport.json for legacy)
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Modes
213
+
214
+ **API mode** is still the default and recommended. **Local mode** now has full parity with API for exec mapping (fixed); both evaluate the same policies. Messaging runs at assurance L0 by default.
215
+
216
+ ### API Mode (default, recommended)
217
+
218
+ **Best for:** Production, full OAP policy (JSON Schema, assurance, evaluation rules), signed decisions, cloud kill switch, audit logs.
219
+
220
+ ```yaml
221
+ config:
222
+ mode: api
223
+ passportFile: ~/.openclaw/aport/passport.json
224
+ apiUrl: https://api.aport.io
225
+ ```
226
+ Set `APORT_API_KEY` in the environment only if your API requires auth.
227
+
228
+ **How it works:**
229
+ - Plugin loads local passport
230
+ - Sends passport + context to APort API
231
+ - API evaluates (passport NOT stored, stateless)
232
+ - Returns signed decision
233
+ - **Network required**
234
+
235
+ ### Local Mode
236
+
237
+ **Best for:** Privacy, offline use, no network dependency
238
+
239
+ ```yaml
240
+ config:
241
+ mode: local
242
+ passportFile: ~/.openclaw/aport/passport.json
243
+ guardrailScript: ~/.openclaw/.skills/aport-guardrail-bash.sh
244
+ ```
245
+
246
+ **How it works:**
247
+ - Plugin calls local bash script
248
+ - Script evaluates policy using local passport (subset of OAP; see [Verification methods](VERIFICATION_METHODS.md))
249
+ - Returns decision (exit 0 = allow, exit 1 = deny)
250
+ - **No network required**
251
+
252
+ ---
253
+
254
+ ## Troubleshooting
255
+
256
+ ### Plugin not loading
257
+
258
+ ```bash
259
+ # Check plugin list
260
+ openclaw plugins list
261
+
262
+ # Should show: openclaw-aport (enabled)
263
+ ```
264
+
265
+ If not listed:
266
+ 1. Verify installation: `openclaw plugins install /path/to/extensions/openclaw-aport`
267
+ 2. Check config.yaml has `plugins.entries.openclaw-aport.enabled: true`
268
+ 3. Restart OpenClaw gateway
269
+
270
+ ### Tools not being blocked
271
+
272
+ Check:
273
+ 1. **Plugin enabled?** `openclaw plugins list` should show `openclaw-aport (enabled)`
274
+ 2. **Tool mapped?** See tool-to-policy mapping in plugin README
275
+ 3. **Passport allows it?** The installer sets `allowed_commands: ["*"]` by default. If you intentionally tightened the allowlist, re-add the commands you need to `limits.system.command.execute.allowed_commands` in your passport.
276
+ 4. **Script working?** Test directly:
277
+ ```bash
278
+ ~/.openclaw/.skills/aport-guardrail-bash.sh system.command.execute '{"command":"ls"}'
279
+ ```
280
+
281
+ ### Error: "Failed to run guardrail script"
282
+
283
+ Check:
284
+ 1. Script exists: `ls -l ~/.openclaw/.skills/aport-guardrail-bash.sh`
285
+ 2. Script executable: `chmod +x ~/.openclaw/.skills/aport-guardrail-bash.sh`
286
+ 3. Script works: Run test command above
287
+
288
+ ### Guardrail DENY / `oap.passport_version_mismatch`
289
+
290
+ If the guardrail denies every call and `~/.openclaw/aport/decision.json` (or `~/.openclaw/decision.json`) shows reason `oap.passport_version_mismatch` ("Passport spec version is 'unknown', expected 'oap/1.0'"):
291
+
292
+ 1. **Passport must have `spec_version: "oap/1.0"`** (OAP spec). If your passport has only `"version": "1.0.0"` in metadata and no top-level `spec_version`, it was created by an older or non–spec-compliant tool.
293
+ 2. **Limits must be nested per capability.** The verifier expects e.g. `limits["system.command.execute"]` with `allowed_commands`, `blocked_patterns`, not a flat `limits.allowed_commands` at the top level.
294
+
295
+ **Fix:** Re-run the installer so it can normalize the passport:
296
+
297
+ ```bash
298
+ npx @aporthq/aport-agent-guardrails
299
+ ```
300
+
301
+ Choose to overwrite the existing passport when prompted, or run the wizard with `--output` to a new file. The installer now ensures `spec_version: "oap/1.0"` and nested limits. If you prefer to fix the file manually, add `"spec_version": "oap/1.0"` at the top level and move any top-level `allowed_commands` / `blocked_patterns` under `limits["system.command.execute"]`. See [agent-passport/spec/oap](https://github.com/aporthq/agent-passport/tree/main/spec/oap) for the canonical schema.
302
+
303
+ ---
304
+
305
+ ## Configuration Reference
306
+
307
+ ### Minimum Configuration (API mode — default)
308
+
309
+ ```yaml
310
+ plugins:
311
+ enabled: true
312
+ entries:
313
+ openclaw-aport:
314
+ enabled: true
315
+ config:
316
+ mode: api
317
+ passportFile: ~/.openclaw/aport/passport.json
318
+ apiUrl: https://api.aport.io
319
+ failClosed: true
320
+ ```
321
+
322
+ ### Full Configuration (API mode)
323
+
324
+ ```yaml
325
+ plugins:
326
+ enabled: true
327
+ entries:
328
+ openclaw-aport:
329
+ enabled: true
330
+ config:
331
+ # Mode: "api" (default) or "local"
332
+ mode: api
333
+
334
+ # Passport file location
335
+ passportFile: ~/.openclaw/aport/passport.json
336
+
337
+ # For local mode: path to guardrail script
338
+ guardrailScript: ~/.openclaw/.skills/aport-guardrail-bash.sh
339
+
340
+ # For API mode: APort API endpoint
341
+ apiUrl: https://api.aport.io # or your self-hosted API URL
342
+ # Optional: set APORT_API_KEY in the environment if your API requires auth
343
+
344
+ # Fail-closed: block on error (default: true)
345
+ failClosed: true
346
+ ```
347
+
348
+ ### Minimum Configuration (Local mode)
349
+
350
+ ```yaml
351
+ plugins:
352
+ enabled: true
353
+ entries:
354
+ openclaw-aport:
355
+ enabled: true
356
+ config:
357
+ mode: local
358
+ passportFile: ~/.openclaw/aport/passport.json
359
+ guardrailScript: ~/.openclaw/.skills/aport-guardrail-bash.sh
360
+ failClosed: true
361
+ ```
362
+
363
+ ---
364
+
365
+ ## Tool-to-Policy Mapping
366
+
367
+ The plugin automatically maps OpenClaw tool names to APort policy packs:
368
+
369
+ | OpenClaw Tool | APort Policy |
370
+ |---------------|--------------|
371
+ | `git.create_pr`, `git.merge`, `git.push` | `code.repository.merge.v1` |
372
+ | `exec.run`, `system.command.*`, `bash` | `system.command.execute.v1` |
373
+ | `message.send`, `messaging.*` | `messaging.message.send.v1` |
374
+ | `mcp.*` | `mcp.tool.execute.v1` |
375
+ | `session.create` | `agent.session.create.v1` |
376
+ | `tool.register` | `agent.tool.register.v1` |
377
+ | `payment.refund` | `finance.payment.refund.v1` |
378
+ | `payment.charge` | `finance.payment.charge.v1` |
379
+ | `data.export` | `data.export.create.v1` |
380
+
381
+ Unmapped tools are allowed (fail-open for flexibility).
382
+
383
+ ---
384
+
385
+ ## Security Considerations
386
+
387
+ ### Fail-Closed by Default
388
+
389
+ By default, `failClosed: true` means **any error blocks the tool**:
390
+ - Script not found → BLOCK
391
+ - API unreachable → BLOCK
392
+ - Invalid passport → BLOCK
393
+
394
+ This is secure-by-default. To fail-open (not recommended):
395
+
396
+ ```yaml
397
+ config:
398
+ failClosed: false # Allow on error (NOT RECOMMENDED)
399
+ ```
400
+
401
+ ### Plugin Trust
402
+
403
+ Plugins run **in-process** with full access to OpenClaw. Only install from trusted sources:
404
+ - Official APort plugin (this)
405
+ - Your own forks/modifications
406
+
407
+ Use `plugins.allow` allowlist in config.yaml:
408
+
409
+ ```yaml
410
+ plugins:
411
+ allow:
412
+ - openclaw-aport
413
+ - your-other-trusted-plugin
414
+ ```
415
+
416
+ ### Bypass Prevention
417
+
418
+ **With plugin:** AI **cannot** bypass policy enforcement. The platform calls `before_tool_call` before every tool.
419
+
420
+ **Without plugin (AGENTS.md only):** AI **can** bypass via:
421
+ - Prompt injection
422
+ - Forgetting to call guardrail
423
+ - Deciding action is "safe"
424
+
425
+ **Bottom line:** Plugin = deterministic. AGENTS.md = best-effort (not secure).
426
+
427
+ ---
428
+
429
+ ## Next Steps
430
+
431
+ 1. **Run the setup (once):** From repo root: `./bin/openclaw`. Use the default config dir or choose a path.
432
+ 2. **Choose "yes"** when prompted to install the plugin.
433
+ 3. **Start OpenClaw** with the generated config: `openclaw gateway start --config <your-config-dir>/config.yaml` (e.g. `~/.openclaw/config.yaml`).
434
+ 4. **Test enforcement:** Run the agent; try an allowed action (e.g. `node --version`) and one that should be blocked by your passport (e.g. `rm -rf /`). The plugin blocks before the tool runs.
435
+ 5. **Customize passport:** Edit `<config-dir>/aport/passport.json` (or `<config-dir>/passport.json` for legacy) to adjust limits and allowed commands.
436
+
437
+ ---
438
+
439
+ ## Support
440
+
441
+ - **Full documentation:** [`extensions/openclaw-aport/README.md`](../extensions/openclaw-aport/README.md)
442
+ - **Issues:** [GitHub Issues](https://github.com/aporthq/aport-agent-guardrails/issues)
443
+ - **Discord:** [discord.gg/aport](https://discord.gg/aport)
444
+
445
+ ---
446
+
447
+ ## Summary
448
+
449
+ ✅ **One command:** Run `./bin/openclaw` from the repo root to create passport, install plugin, write config and wrappers, and verify. You only need this once per config dir.
450
+ ✅ **Deterministic enforcement:** The plugin runs before every tool; the platform enforces, the AI cannot bypass.
451
+ ✅ **Fail-closed:** Blocks on error by default.
452
+ ✅ **API (default) or local:** Full OAP via API, or local script for offline/privacy.
453
+ ✅ **Zero OpenClaw core changes:** Uses the existing OpenClaw plugin API.
454
+
455
+ **After setup, start OpenClaw with the generated config—your agent is then secured by APort policy.**
456
+
457
+ ---
458
+
459
+ ## How it all fits together
460
+
461
+ | Step | What happens |
462
+ |------|----------------|
463
+ | You run `./bin/openclaw` | Script asks for config dir, creates passport, installs plugin, writes `config.yaml`, installs wrappers in `<config-dir>/.skills/`, and **updates the passport** with default `allowed_commands` (bash, sh, ls, mkdir, npm, etc.) so normal exec works. |
464
+ | `config.yaml` | Contains `passportFile` and `guardrailScript` pointing to `<config-dir>/aport/passport.json` and `<config-dir>/.skills/aport-guardrail-bash.sh`. |
465
+ | Passport allowlist | The installer sets `allowed_commands: ["*"]` automatically. No manual editing needed unless you want to restrict commands. |
466
+ | Wrapper script | `<config-dir>/.skills/aport-guardrail-bash.sh` is a small script that calls this repo’s `bin/aport-guardrail-bash.sh` with the same args and env (passport path, etc.). |
467
+ | You start OpenClaw | `openclaw gateway start --config <config-dir>/config.yaml` (or use that config when running the agent). |
468
+ | On every tool call | OpenClaw runs the plugin’s `before_tool_call` hook → plugin calls the guardrail script with tool name and params → script evaluates against passport and policy → allow = tool runs, deny = plugin returns `block: true` and the tool never runs. |
469
+
470
+ **So: one run of `./bin/openclaw` is all you need.** No manual editing of config or wrapper paths if you use the default config dir.
package/docs/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # APort Agent Guardrails — Documentation
2
+
3
+ **Public documentation** (for users integrating OpenClaw + APort guardrails):
4
+
5
+ | Doc | Purpose |
6
+ |-----|---------|
7
+ | [QUICKSTART_OPENCLAW_PLUGIN.md](QUICKSTART_OPENCLAW_PLUGIN.md) | **OpenClaw plugin** — 5-minute setup, deterministic enforcement (RECOMMENDED) |
8
+ | [**HOSTED_PASSPORT_SETUP.md**](HOSTED_PASSPORT_SETUP.md) | **Use passport from aport.io** — create at aport.io, then `npx @aporthq/aport-agent-guardrails <agent_id>` (or choose hosted in wizard) |
9
+ | [QUICKSTART.md](QUICKSTART.md) | Interactive setup and step-by-step with passport wizard |
10
+ | [OPENCLAW_LOCAL_INTEGRATION.md](OPENCLAW_LOCAL_INTEGRATION.md) | Full OpenClaw setup: API, passport, policies, Python example |
11
+ | [OPENCLAW_TOOLS_AND_POLICIES.md](OPENCLAW_TOOLS_AND_POLICIES.md) | exec, allowed_commands, unmapped tools, passport limits |
12
+ | [TOOL_POLICY_MAPPING.md](TOOL_POLICY_MAPPING.md) | How tool names map to policy packs |
13
+ | [IMPLEMENTING_YOUR_OWN_EVALUATOR.md](IMPLEMENTING_YOUR_OWN_EVALUATOR.md) | Build your own evaluator from the OAP spec |
14
+ | [OPENCLAW_COMPATIBILITY.md](OPENCLAW_COMPATIBILITY.md) | OpenClaw version alignment, paths, OPENCLAW_HOME |
15
+ | [AGENTS.md.example](AGENTS.md.example) | Example AGENTS.md section for pre-action authorization |
16
+ | [REPO_LAYOUT.md](REPO_LAYOUT.md) | What `bin/`, `src/`, `extensions/`, `external/` do |
17
+
18
+ **Launch & checklists** (internal / maintainers):
19
+
20
+ | Doc | Purpose |
21
+ |-----|---------|
22
+ | [LAUNCH_READINESS_CHECKLIST.md](LAUNCH_READINESS_CHECKLIST.md) | Launch checklist + guardrail execution gate |
23
+ | [launch/LAUNCH_STRATEGY_SUMMARY.md](launch/LAUNCH_STRATEGY_SUMMARY.md) | Timing, content, evidence, pre-flight |
24
+ | [launch/QUICK_LAUNCH_CHECKLIST.md](launch/QUICK_LAUNCH_CHECKLIST.md) | Final verification before each post |
25
+ | [launch/OPENCLAW_FEEDBACK_AND_FIXES.md](launch/OPENCLAW_FEEDBACK_AND_FIXES.md) | OpenClaw feedback summary + two fixes (allowlist, capabilities) |
26
+ | [launch/POST_1_VALENTINE_IMPROVED.md](launch/POST_1_VALENTINE_IMPROVED.md) | Post 1 draft (Valentine) |
27
+ | [launch/POST_2_GUARDRAIL_IMPROVED.md](launch/POST_2_GUARDRAIL_IMPROVED.md) | Post 2 draft (Guardrail) |
28
+ | [ANNOUNCEMENT_GUIDE.md](ANNOUNCEMENT_GUIDE.md) | Announcement messaging and materials |
@@ -0,0 +1,87 @@
1
+ # Release process and version policy
2
+
3
+ **Current release:** 1.0.8 (see [CHANGELOG.md](../CHANGELOG.md)).
4
+
5
+ We keep **one version number** across all published packages (Node core, Python core, and every framework adapter). That avoids “core is 1.2 but CLI is 0.9” and keeps the story simple for users and support.
6
+
7
+ ---
8
+
9
+ ## 1. Version policy summary
10
+
11
+ | What | Policy |
12
+ |------|--------|
13
+ | **Core packages** | `@aporthq/aport-agent-guardrails` (root/CLI), `@aporthq/aport-agent-guardrails-core`, `aport-agent-guardrails` (Python) always share the same version (e.g. `1.3.0`). |
14
+ | **Framework adapters** | Node: `@aporthq/aport-agent-guardrails-langchain`, `-crewai`, `-cursor` (published). `-n8n` is **not published yet** (coming soon). Python: `aport-agent-guardrails-langchain`, `aport-agent-guardrails-crewai`. They depend on core with `>=` and publish with the same version as core. |
15
+ | **Repo tag** | Git tag `v1.3.0` matches the released version so docs and installs stay aligned. |
16
+
17
+ So: **one version for the whole suite.** If only the LangChain adapter changed, we still bump core (and all other packages) to the same new version so everything stays in lockstep.
18
+
19
+ ---
20
+
21
+ ## 1.1. Why two npm packages: @aporthq/aport-agent-guardrails vs @aporthq/aport-agent-guardrails-core?
22
+
23
+ | Package | What it is | Who installs it |
24
+ |---------|------------|------------------|
25
+ | **@aporthq/aport-agent-guardrails** (root) | The **CLI and setup tool**: `bin/agent-guardrails`, framework installers (bash scripts), docs, OpenClaw extension. No TypeScript evaluator — it runs the passport wizard and writes config. | Users who want the one-line setup: `npx @aporthq/aport-agent-guardrails langchain` (or cursor, crewai, openclaw). |
26
+ | **@aporthq/aport-agent-guardrails-core** | The **Node library**: Evaluator, config, passport loading, `verify` / `verifySync`. Used inside your app to enforce policy. | Anyone using the **framework adapters** (e.g. `@aporthq/aport-agent-guardrails-langchain`) — they depend on core. Also apps that want only the evaluator without the CLI. |
27
+
28
+ So: **root = CLI/setup**; **core = library**. We publish core so that (1) the adapters can declare it as a dependency and npm can resolve it, and (2) users can install just the evaluator if they don’t need the full CLI.
29
+
30
+ ---
31
+
32
+ ## 2. Tooling
33
+
34
+ - **Changesets** (Node): fixed mode so all workspace packages are in one “fixed” group and get the same version on release.
35
+ - **sync-version script**: after `changeset version`, copies the new version from root `package.json` into all Python `pyproject.toml` and `aport_guardrails/__init__.py`.
36
+
37
+ ---
38
+
39
+ ## 3. Release flow
40
+
41
+ 1. **Merge PRs** → run automated tests (e.g. CI).
42
+ 2. **Bump version and changelogs**
43
+ ```bash
44
+ npm run version
45
+ ```
46
+ This runs `changeset version` (updates all Node `package.json` and CHANGELOGs) then `node scripts/sync-version.mjs` (updates Python packages to the same version).
47
+ 3. **Commit** the version bump and changelog updates (e.g. “chore(release): 1.3.0”).
48
+ 4. **Tag and push** — this triggers the release workflow and publishes both npm and PyPI:
49
+ ```bash
50
+ git tag v1.3.0
51
+ git push origin v1.3.0
52
+ ```
53
+ 5. **CI (`.github/workflows/release.yml`)**: on tag push `v*`:
54
+ - **publish-npm**: publishes the **root** package `@aporthq/aport-agent-guardrails` (CLI) and workspace packages `@aporthq/aport-agent-guardrails-core`, `-langchain`, `-crewai`, `-cursor` to npm. The **n8n** package is not published yet (coming soon). Uses `NPM_TOKEN` secret.
55
+ - **publish-python**: builds and publishes `aport-agent-guardrails`, `aport-agent-guardrails-langchain`, and `aport-agent-guardrails-crewai` to PyPI (uses `PYPI_TOKEN` secret). Skips upload if aport-agent-guardrails version already exists.
56
+ - **create-release**: creates the GitHub Release with install notes for both ecosystems.
57
+
58
+ **PyPI**: In [PyPI project settings](https://pypi.org/help/#project-urls), set Repository and (if using trusted publishing) add this repo and workflow name **Release**. Otherwise configure the `PYPI_TOKEN` secret in the GitHub repo.
59
+
60
+ ---
61
+
62
+ ## 4. Adding a changeset (before release)
63
+
64
+ After making any change that should go into the next release:
65
+
66
+ ```bash
67
+ npx changeset
68
+ # or
69
+ npm run changeset
70
+ ```
71
+
72
+ - Choose **patch** / **minor** / **major**.
73
+ - Write a short summary for the changelog.
74
+ - Commit the new file under `.changeset/`.
75
+
76
+ When you run `npm run version`, that changeset will drive a single version bump for the whole fixed group; then `sync-version` keeps Python in sync.
77
+
78
+ ---
79
+
80
+ ## 5. Long-term flexibility
81
+
82
+ If we later need finer control (e.g. enterprise adapters that shouldn’t force a full suite release), we can:
83
+
84
+ - Move to independent versioning for some adapters, and/or
85
+ - Introduce a “meta” package that pins compatible versions.
86
+
87
+ For now, a single version across all packages keeps the ecosystem coherent and avoids support confusion.
@@ -0,0 +1,47 @@
1
+ # Repository Layout
2
+
3
+ Quick reference for what each part of the repo does.
4
+
5
+ ## `bin/`
6
+
7
+ CLI and guardrail entrypoints used by OpenClaw (or any framework):
8
+
9
+ | Script | Purpose |
10
+ |--------|---------|
11
+ | **openclaw** | One-command setup: passport wizard, plugin install, config, `.skills` wrappers |
12
+ | **aport-create-passport.sh** | Interactive OAP v1.0 passport wizard (capabilities, limits, L0 default) |
13
+ | **aport-guardrail-bash.sh** | **Local evaluator** — evaluates policy using passport + `external/aport-policies`; no API, no network |
14
+ | **aport-guardrail-api.sh** | Calls APort API (cloud or self-hosted); uses **src/evaluator.js** |
15
+ | **aport-guardrail.sh** | Backward-compat wrapper → runs bash guardrail |
16
+ | **aport-guardrail-v2.sh** | Backward-compat wrapper → runs API guardrail |
17
+ | **aport-status.sh** | Show passport summary and status |
18
+
19
+ ## `src/`
20
+
21
+ Node.js code for **API-based** evaluation and optional proxy:
22
+
23
+ | File | Purpose |
24
+ |------|---------|
25
+ | **evaluator.js** | **APort API client** — calls `POST /api/verify/policy/{packId}` with passport (local mode) or `agent_id` (cloud mode). Used by `bin/aport-guardrail-api.sh` and by any programmatic caller (e.g. `require('./src/evaluator')`). Supports `APORT_API_URL`, `APORT_AGENT_ID`, `APORT_API_KEY`. Loads policy packs from `external/aport-policies` and passports from file. |
26
+ | **server/index.js** | **Optional HTTP proxy** — forwards requests to the agent-passport API (e.g. `APORT_API_BASE=https://api.aport.io`). Run with `npm run server` (port 8788). Use when you need a proxy in front of the API; most users call the API directly. |
27
+
28
+ **Summary:** For **local evaluation with no network**, the repo uses **bin/aport-guardrail-bash.sh** (bash + jq + policies from submodule). For **API evaluation** (cloud or self-hosted agent-passport), it uses **src/evaluator.js** (Node) and **bin/aport-guardrail-api.sh** (which invokes the evaluator).
29
+
30
+ ## `extensions/openclaw-aport/`
31
+
32
+ OpenClaw plugin — `before_tool_call` hook that invokes the guardrail script or API before every tool execution. Deterministic enforcement; AI cannot bypass.
33
+
34
+ ## `external/`
35
+
36
+ Git submodules (run `npm run sync-submodules` or `sync-submodules:latest`):
37
+
38
+ - **aport-spec** — OAP passport/decision schema and spec
39
+ - **aport-policies** — Policy packs (system.command.execute, messaging.message.send, mcp.tool.execute, etc.)
40
+
41
+ ## `local-overrides/`
42
+
43
+ Local policy and passport templates that override or extend the submodule content (e.g. `system.command.execute.v1` when the policy is not yet in aport-policies).
44
+
45
+ ## `tests/`
46
+
47
+ OAP v1 test suite: guardrail allow/deny, passport creation, suspend (passport status), four verification methods, API evaluator (when API is up). Run with `make test`.