@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,162 @@
1
+ {
2
+ "id": "agent.session.create.v1",
3
+ "name": "Agent Session Creation Policy",
4
+ "description": "Pre-action governance for AI agent session creation. Enforces session limits, duration restrictions, concurrent session controls, and resource allocation for secure multi-session agent deployments.",
5
+ "version": "1.0.0",
6
+ "status": "active",
7
+ "requires_capabilities": ["agent.session.create"],
8
+ "min_assurance": "L0",
9
+ "limits_required": ["max_sessions_per_user", "max_session_duration"],
10
+ "required_fields": ["user_id", "session_type"],
11
+ "optional_fields": [
12
+ "session_name",
13
+ "requested_duration",
14
+ "resources",
15
+ "metadata",
16
+ "parent_session_id",
17
+ "tags"
18
+ ],
19
+ "enforcement": {
20
+ "session_limit_enforced": true,
21
+ "duration_limit_enforced": true,
22
+ "concurrent_session_enforced": true,
23
+ "resource_quota_enforced": true,
24
+ "session_type_enforced": true
25
+ },
26
+ "mcp": {
27
+ "require_allowlisted_if_present": false
28
+ },
29
+ "advice": [
30
+ "Enforce session limits per user to prevent resource exhaustion",
31
+ "Set maximum session durations to prevent zombie sessions",
32
+ "Limit concurrent sessions to manage system load",
33
+ "Track session creation for billing and auditing",
34
+ "Use session types to apply different policies",
35
+ "Implement session tagging for organization and tracking",
36
+ "Monitor session creation patterns for anomalies",
37
+ "Log all session creations for Verifiable Attestation",
38
+ "Subscribe to status webhooks for instant suspend",
39
+ "Implement progressive limits for new users"
40
+ ],
41
+ "required_context": {
42
+ "$schema": "http://json-schema.org/draft-07/schema#",
43
+ "type": "object",
44
+ "required": ["user_id", "session_type"],
45
+ "properties": {
46
+ "user_id": {
47
+ "type": "string",
48
+ "minLength": 1,
49
+ "maxLength": 200,
50
+ "description": "User identifier for session owner"
51
+ },
52
+ "session_type": {
53
+ "type": "string",
54
+ "enum": ["interactive", "batch", "webhook", "scheduled", "ephemeral"],
55
+ "description": "Type of session being created"
56
+ },
57
+ "session_name": {
58
+ "type": "string",
59
+ "maxLength": 200,
60
+ "description": "Human-readable session name"
61
+ },
62
+ "requested_duration": {
63
+ "type": "integer",
64
+ "minimum": 60,
65
+ "maximum": 86400,
66
+ "description": "Requested session duration in seconds"
67
+ },
68
+ "resources": {
69
+ "type": "object",
70
+ "properties": {
71
+ "memory_mb": {
72
+ "type": "integer",
73
+ "minimum": 128,
74
+ "maximum": 32768,
75
+ "description": "Requested memory in MB"
76
+ },
77
+ "cpu_millicores": {
78
+ "type": "integer",
79
+ "minimum": 100,
80
+ "maximum": 8000,
81
+ "description": "Requested CPU in millicores"
82
+ },
83
+ "storage_gb": {
84
+ "type": "integer",
85
+ "minimum": 1,
86
+ "maximum": 1000,
87
+ "description": "Requested storage in GB"
88
+ }
89
+ },
90
+ "description": "Resource requirements for session"
91
+ },
92
+ "metadata": {
93
+ "type": "object",
94
+ "additionalProperties": true,
95
+ "maxProperties": 50,
96
+ "description": "Custom metadata for session"
97
+ },
98
+ "parent_session_id": {
99
+ "type": "string",
100
+ "description": "Parent session ID for nested sessions"
101
+ },
102
+ "tags": {
103
+ "type": "array",
104
+ "items": { "type": "string" },
105
+ "maxItems": 20,
106
+ "description": "Tags for session organization"
107
+ },
108
+ "mcp_servers": {
109
+ "type": "array",
110
+ "items": { "type": "string" },
111
+ "description": "MCP servers to be used in session"
112
+ },
113
+ "mcp_tools": {
114
+ "type": "array",
115
+ "items": { "type": "string" },
116
+ "description": "MCP tools to be used in session"
117
+ },
118
+ "mcp_session": {
119
+ "type": "string",
120
+ "description": "MCP session identifier for audit trail"
121
+ }
122
+ }
123
+ },
124
+ "evaluation_rules_version": "1.0",
125
+ "evaluation_rules": [
126
+ {
127
+ "name": "session_duration_limit",
128
+ "type": "expression",
129
+ "condition": "!context.requested_duration || context.requested_duration <= limits.max_session_duration",
130
+ "deny_code": "oap.duration_limit_exceeded",
131
+ "description": "Session duration must not exceed limit"
132
+ },
133
+ {
134
+ "name": "session_type_allowed",
135
+ "type": "expression",
136
+ "condition": "!limits.allowed_session_types || limits.allowed_session_types.includes(context.session_type)",
137
+ "deny_code": "oap.session_type_not_allowed",
138
+ "description": "Session type must be in allowed list"
139
+ },
140
+ {
141
+ "name": "resource_quota",
142
+ "type": "custom_validator",
143
+ "validator": "validateResourceQuota",
144
+ "deny_code": "oap.resource_quota_exceeded",
145
+ "description": "Requested resources must not exceed quota"
146
+ },
147
+ {
148
+ "name": "concurrent_session_limit",
149
+ "type": "custom_validator",
150
+ "validator": "validateConcurrentSessions",
151
+ "deny_code": "oap.concurrent_limit_exceeded",
152
+ "description": "Agent must not exceed concurrent session limit"
153
+ }
154
+ ],
155
+ "cache": {
156
+ "default_ttl_seconds": 60,
157
+ "suspend_invalidate_seconds": 30
158
+ },
159
+ "deprecation": null,
160
+ "created_at": "2026-02-14T00:00:00Z",
161
+ "updated_at": "2026-02-14T00:00:00Z"
162
+ }
@@ -0,0 +1,361 @@
1
+ # Agent Tool Registration Policy v1
2
+
3
+ **Policy ID:** `agent.tool.register.v1`
4
+ **Status:** Active
5
+ **Min Assurance:** L2
6
+
7
+ ## Overview
8
+
9
+ The Agent Tool Registration Policy provides pre-action governance for AI agent tool registration. This policy enforces tool naming conventions, capability declarations, security validations, and registration limits to ensure a secure and well-managed tool ecosystem.
10
+
11
+ ## Use Cases
12
+
13
+ - **Tool Marketplaces**: Registering tools in agent marketplaces
14
+ - **Custom Tools**: Registering custom functions for agent use
15
+ - **MCP Tools**: Registering MCP tool wrappers
16
+ - **API Integrations**: Registering API endpoint tools
17
+ - **Workflow Tools**: Registering multi-step workflow tools
18
+
19
+ ## Required Capabilities
20
+
21
+ - `agent.tool.register`
22
+
23
+ ## Required Limits
24
+
25
+ - `max_tools_per_agent` (integer): Maximum tools an agent can register
26
+ - `max_registrations_per_day` (integer): Maximum registrations per day
27
+
28
+ ## Optional Limits
29
+
30
+ - `allowed_tool_types` (array): Allowed tool types
31
+ - `allowed_capabilities` (array): Allowed capability declarations
32
+ - `require_schema` (boolean): Require JSON schema for tools
33
+ - `require_version` (boolean): Require semantic versioning
34
+ - `require_repository` (boolean): Require source repository URL
35
+ - `allowed_licenses` (array): Allowed licenses
36
+
37
+ ## Context Schema
38
+
39
+ ### Required Fields
40
+
41
+ - `tool_name` (string): Unique tool name (lowercase, alphanumeric, dots, dashes)
42
+ - `tool_type` (enum): Tool type (function, mcp_tool, api, command, workflow, agent)
43
+ - `capabilities` (array): List of required capabilities
44
+
45
+ ### Optional Fields
46
+
47
+ - `tool_description` (string): Human-readable description
48
+ - `tool_version` (string): Semantic version
49
+ - `schema` (object): JSON Schema for parameters
50
+ - `author` (string): Tool author
51
+ - `repository` (string): Source code repository URL
52
+ - `license` (enum): Tool license
53
+ - `tags` (array): Categorization tags
54
+ - `metadata` (object): Custom metadata
55
+ - `mcp_servers`, `mcp_tools`, `mcp_session`: MCP integration fields
56
+
57
+ ## Tool Types
58
+
59
+ - **function**: Simple callable function
60
+ - **mcp_tool**: MCP protocol tool wrapper
61
+ - **api**: RESTful API endpoint wrapper
62
+ - **command**: Shell command wrapper
63
+ - **workflow**: Multi-step workflow orchestrator
64
+ - **agent**: Nested agent invocation
65
+
66
+ ## Evaluation Rules
67
+
68
+ 1. **passport_status_active**: Passport must be active
69
+ 2. **tool_register_capability**: Agent must have `agent.tool.register` capability
70
+ 3. **tool_count_limit**: Must not exceed max tools per agent
71
+ 4. **daily_registration_limit**: Must not exceed daily limit
72
+ 5. **tool_name_unique**: Tool name must be unique
73
+ 6. **tool_type_allowed**: Tool type must be allowed
74
+ 7. **capability_allowed**: All capabilities must be allowed
75
+ 8. **naming_convention**: Tool name must follow convention
76
+
77
+ ## Example Passport Limits
78
+
79
+ ```json
80
+ {
81
+ "limits": {
82
+ "agent.tool.register": {
83
+ "max_tools_per_agent": 100,
84
+ "max_registrations_per_day": 50,
85
+ "allowed_tool_types": [
86
+ "function",
87
+ "mcp_tool",
88
+ "api",
89
+ "command",
90
+ "workflow"
91
+ ],
92
+ "allowed_capabilities": [
93
+ "system.command.execute",
94
+ "mcp.tool.execute",
95
+ "data.export",
96
+ "messaging.message.send"
97
+ ],
98
+ "require_schema": true,
99
+ "require_version": true,
100
+ "require_repository": false,
101
+ "allowed_licenses": [
102
+ "MIT",
103
+ "Apache-2.0",
104
+ "BSD-3-Clause",
105
+ "ISC",
106
+ "proprietary"
107
+ ]
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ ## Example Request Context
114
+
115
+ ```json
116
+ {
117
+ "tool_name": "github.pr.create",
118
+ "tool_type": "mcp_tool",
119
+ "capabilities": ["mcp.tool.execute", "code.repository.merge"],
120
+ "tool_description": "Create a GitHub pull request",
121
+ "tool_version": "1.0.0",
122
+ "schema": {
123
+ "$schema": "http://json-schema.org/draft-07/schema#",
124
+ "type": "object",
125
+ "required": ["repo", "title", "head", "base"],
126
+ "properties": {
127
+ "repo": { "type": "string" },
128
+ "title": { "type": "string" },
129
+ "head": { "type": "string" },
130
+ "base": { "type": "string" },
131
+ "body": { "type": "string" }
132
+ }
133
+ },
134
+ "author": "MyOrg Engineering",
135
+ "repository": "https://github.com/myorg/tools",
136
+ "license": "MIT",
137
+ "tags": ["github", "pr", "git"]
138
+ }
139
+ ```
140
+
141
+ ## Example Decision (Allow)
142
+
143
+ ```json
144
+ {
145
+ "decision_id": "dec_tool001",
146
+ "policy_id": "agent.tool.register.v1",
147
+ "passport_id": "pass_abc123",
148
+ "owner_id": "org_12345",
149
+ "assurance_level": "L2",
150
+ "allow": true,
151
+ "reasons": [{
152
+ "code": "oap.allowed",
153
+ "message": "All policy checks passed"
154
+ }],
155
+ "issued_at": "2026-02-14T22:00:00Z",
156
+ "expires_at": "2026-02-14T22:05:00Z",
157
+ "passport_digest": "sha256:...",
158
+ "signature": "ed25519:...",
159
+ "kid": "oap:registry:key-2026-02"
160
+ }
161
+ ```
162
+
163
+ ## Example Decision (Deny - Tool Limit)
164
+
165
+ ```json
166
+ {
167
+ "decision_id": "dec_tool002",
168
+ "policy_id": "agent.tool.register.v1",
169
+ "passport_id": "pass_abc123",
170
+ "owner_id": "org_12345",
171
+ "assurance_level": "L2",
172
+ "allow": false,
173
+ "reasons": [{
174
+ "code": "oap.tool_limit_exceeded",
175
+ "message": "Agent has reached maximum of 100 tool registrations"
176
+ }],
177
+ "issued_at": "2026-02-14T22:00:00Z",
178
+ "expires_at": "2026-02-14T22:05:00Z",
179
+ "passport_digest": "sha256:...",
180
+ "signature": "ed25519:...",
181
+ "kid": "oap:registry:key-2026-02"
182
+ }
183
+ ```
184
+
185
+ ## Tool Naming Convention
186
+
187
+ Tool names must follow the pattern: `^[a-z0-9][a-z0-9._-]*[a-z0-9]$`
188
+
189
+ **Valid Names:**
190
+ - `github.pr.create`
191
+ - `stripe-payment-create`
192
+ - `my_custom_tool`
193
+ - `tool-v2.0`
194
+
195
+ **Invalid Names:**
196
+ - `GitHub.PR.Create` (uppercase)
197
+ - `-tool-name` (starts with dash)
198
+ - `tool.name.` (ends with dot)
199
+ - `tool name` (contains space)
200
+
201
+ ## Security Best Practices
202
+
203
+ 1. **Tool Limits**: Prevent namespace pollution with registration limits
204
+ 2. **Capability Declarations**: Require explicit capability declarations
205
+ 3. **Schema Validation**: Enforce JSON schemas for parameter safety
206
+ 4. **Versioning**: Use semantic versioning for compatibility
207
+ 5. **License Checking**: Validate licenses for compliance
208
+ 6. **Repository Links**: Track source code for security audits
209
+ 7. **Uniqueness**: Enforce unique tool names to prevent conflicts
210
+ 8. **Audit Logging**: Log all registrations for security review
211
+ 9. **Progressive Limits**: Start strict and relax for trusted developers
212
+ 10. **Status Webhooks**: Subscribe for instant revocation
213
+
214
+ ## Error Codes
215
+
216
+ - `oap.passport_suspended`: Passport is not active
217
+ - `oap.unknown_capability`: Missing agent.tool.register capability
218
+ - `oap.tool_limit_exceeded`: Exceeded max tools per agent
219
+ - `oap.daily_limit_exceeded`: Exceeded daily registration limit
220
+ - `oap.tool_already_exists`: Tool name already registered
221
+ - `oap.tool_type_not_allowed`: Tool type not allowed
222
+ - `oap.capability_not_allowed`: Capability not allowed
223
+ - `oap.invalid_tool_name`: Tool name doesn't follow convention
224
+
225
+ ## Integration Examples
226
+
227
+ ### TypeScript (Tool Registry)
228
+
229
+ ```typescript
230
+ import axios from 'axios';
231
+
232
+ interface ToolRegistration {
233
+ toolName: string;
234
+ toolType: 'function' | 'mcp_tool' | 'api' | 'command' | 'workflow' | 'agent';
235
+ capabilities: string[];
236
+ toolDescription?: string;
237
+ toolVersion?: string;
238
+ schema?: object;
239
+ author?: string;
240
+ repository?: string;
241
+ license?: string;
242
+ tags?: string[];
243
+ metadata?: Record<string, any>;
244
+ }
245
+
246
+ async function registerTool(
247
+ passport: Passport,
248
+ registration: ToolRegistration
249
+ ): Promise<Tool> {
250
+ const context = {
251
+ tool_name: registration.toolName,
252
+ tool_type: registration.toolType,
253
+ capabilities: registration.capabilities,
254
+ tool_description: registration.toolDescription,
255
+ tool_version: registration.toolVersion,
256
+ schema: registration.schema,
257
+ author: registration.author,
258
+ repository: registration.repository,
259
+ license: registration.license,
260
+ tags: registration.tags,
261
+ metadata: registration.metadata
262
+ };
263
+
264
+ // Check policy
265
+ const decision = await axios.post('https://api.aport.io/v1/decide', {
266
+ passport_id: passport.passport_id,
267
+ policy_id: 'agent.tool.register.v1',
268
+ context
269
+ });
270
+
271
+ if (!decision.data.allow) {
272
+ throw new Error(`Tool registration blocked: ${decision.data.reasons[0].message}`);
273
+ }
274
+
275
+ // Register tool
276
+ const tool = await registerToolInDatabase(context);
277
+
278
+ // Publish to tool registry
279
+ await publishToolToRegistry(tool);
280
+
281
+ return tool;
282
+ }
283
+ ```
284
+
285
+ ### Python (FastAPI)
286
+
287
+ ```python
288
+ from pydantic import BaseModel, Field
289
+ import httpx
290
+
291
+ class ToolRegistration(BaseModel):
292
+ tool_name: str = Field(..., pattern=r'^[a-z0-9][a-z0-9._-]*[a-z0-9]$')
293
+ tool_type: str = Field(..., pattern=r'^(function|mcp_tool|api|command|workflow|agent)$')
294
+ capabilities: list[str]
295
+ tool_description: str | None = None
296
+ tool_version: str | None = Field(None, pattern=r'^\d+\.\d+\.\d+')
297
+ schema_: dict | None = Field(None, alias='schema')
298
+ author: str | None = None
299
+ repository: str | None = None
300
+ license: str | None = None
301
+ tags: list[str] = []
302
+ metadata: dict = {}
303
+
304
+ async def register_tool(
305
+ passport: dict,
306
+ registration: ToolRegistration
307
+ ) -> dict:
308
+ context = registration.dict(by_alias=True, exclude_none=True)
309
+
310
+ # Check policy
311
+ async with httpx.AsyncClient() as client:
312
+ response = await client.post(
313
+ "https://api.aport.io/v1/decide",
314
+ json={
315
+ "passport_id": passport["passport_id"],
316
+ "policy_id": "agent.tool.register.v1",
317
+ "context": context
318
+ }
319
+ )
320
+ decision = response.json()
321
+
322
+ if not decision["allow"]:
323
+ raise PermissionError(f"Tool registration blocked: {decision['reasons'][0]['message']}")
324
+
325
+ # Register tool
326
+ tool = await register_tool_in_database(context)
327
+
328
+ # Publish to tool registry
329
+ await publish_tool_to_registry(tool)
330
+
331
+ return tool
332
+ ```
333
+
334
+ ## Tool Discovery
335
+
336
+ Registered tools can be discovered via:
337
+
338
+ ```typescript
339
+ // Search by tags
340
+ const tools = await searchTools({ tags: ['github', 'pr'] });
341
+
342
+ // Search by capability
343
+ const tools = await searchTools({ capability: 'code.repository.merge' });
344
+
345
+ // Search by type
346
+ const tools = await searchTools({ type: 'mcp_tool' });
347
+
348
+ // Full-text search
349
+ const tools = await searchTools({ query: 'pull request' });
350
+ ```
351
+
352
+ ## Version History
353
+
354
+ - **v1.0.0** (2026-02-14): Initial release
355
+
356
+ ## References
357
+
358
+ - [OAP Specification](https://github.com/aporthq/aport-spec)
359
+ - [Tool Registry Guidelines](https://docs.aport.io/tools)
360
+ - [JSON Schema Documentation](https://json-schema.org/)
361
+ - [Semantic Versioning](https://semver.org/)
@@ -0,0 +1,172 @@
1
+ {
2
+ "id": "agent.tool.register.v1",
3
+ "name": "Agent Tool Registration Policy",
4
+ "description": "Pre-action governance for AI agent tool registration. Enforces tool naming conventions, capability declarations, security validations, and registration limits for secure tool ecosystem management.",
5
+ "version": "1.0.0",
6
+ "status": "active",
7
+ "requires_capabilities": ["agent.tool.register"],
8
+ "min_assurance": "L0",
9
+ "limits_required": ["max_tools_per_agent", "max_registrations_per_day"],
10
+ "required_fields": ["tool_name", "tool_type", "capabilities"],
11
+ "optional_fields": [
12
+ "tool_description",
13
+ "tool_version",
14
+ "schema",
15
+ "author",
16
+ "repository",
17
+ "license",
18
+ "tags",
19
+ "metadata"
20
+ ],
21
+ "enforcement": {
22
+ "naming_convention_enforced": true,
23
+ "tool_limit_enforced": true,
24
+ "capability_validation_enforced": true,
25
+ "schema_validation_enforced": true,
26
+ "uniqueness_enforced": true
27
+ },
28
+ "mcp": {
29
+ "require_allowlisted_if_present": false
30
+ },
31
+ "advice": [
32
+ "Enforce tool registration limits to prevent namespace pollution",
33
+ "Validate tool naming conventions for consistency",
34
+ "Require capability declarations for security transparency",
35
+ "Use schema validation for tool parameter safety",
36
+ "Track tool registrations for auditing and discovery",
37
+ "Implement tool versioning for compatibility management",
38
+ "Use tags for tool categorization and search",
39
+ "Log all tool registrations for Verifiable Attestation",
40
+ "Subscribe to status webhooks for instant suspend",
41
+ "Implement progressive limits for new developers"
42
+ ],
43
+ "required_context": {
44
+ "$schema": "http://json-schema.org/draft-07/schema#",
45
+ "type": "object",
46
+ "required": ["tool_name", "tool_type", "capabilities"],
47
+ "properties": {
48
+ "tool_name": {
49
+ "type": "string",
50
+ "minLength": 3,
51
+ "maxLength": 100,
52
+ "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$",
53
+ "description": "Unique tool name (lowercase, alphanumeric, dots, dashes, underscores)"
54
+ },
55
+ "tool_type": {
56
+ "type": "string",
57
+ "enum": ["function", "mcp_tool", "api", "command", "workflow", "agent"],
58
+ "description": "Type of tool being registered"
59
+ },
60
+ "capabilities": {
61
+ "type": "array",
62
+ "items": {
63
+ "type": "string",
64
+ "pattern": "^[a-z0-9][a-z0-9._-]*[a-z0-9]$"
65
+ },
66
+ "minItems": 1,
67
+ "maxItems": 50,
68
+ "description": "List of capabilities this tool requires"
69
+ },
70
+ "tool_description": {
71
+ "type": "string",
72
+ "maxLength": 1000,
73
+ "description": "Human-readable tool description"
74
+ },
75
+ "tool_version": {
76
+ "type": "string",
77
+ "pattern": "^\\d+\\.\\d+\\.\\d+(-[a-z0-9.]+)?(\\+[a-z0-9.]+)?$",
78
+ "description": "Semantic version (e.g., 1.0.0, 1.0.0-beta.1)"
79
+ },
80
+ "schema": {
81
+ "type": "object",
82
+ "description": "JSON Schema for tool parameters"
83
+ },
84
+ "author": {
85
+ "type": "string",
86
+ "maxLength": 200,
87
+ "description": "Tool author name or organization"
88
+ },
89
+ "repository": {
90
+ "type": "string",
91
+ "format": "uri",
92
+ "description": "Source code repository URL"
93
+ },
94
+ "license": {
95
+ "type": "string",
96
+ "enum": [
97
+ "MIT",
98
+ "Apache-2.0",
99
+ "GPL-3.0",
100
+ "BSD-3-Clause",
101
+ "ISC",
102
+ "proprietary"
103
+ ],
104
+ "description": "Tool license"
105
+ },
106
+ "tags": {
107
+ "type": "array",
108
+ "items": { "type": "string" },
109
+ "maxItems": 20,
110
+ "description": "Tags for tool categorization"
111
+ },
112
+ "metadata": {
113
+ "type": "object",
114
+ "additionalProperties": true,
115
+ "maxProperties": 50,
116
+ "description": "Custom metadata for tool"
117
+ },
118
+ "mcp_servers": {
119
+ "type": "array",
120
+ "items": { "type": "string" },
121
+ "description": "MCP servers used by this tool"
122
+ },
123
+ "mcp_tools": {
124
+ "type": "array",
125
+ "items": { "type": "string" },
126
+ "description": "MCP tools used by this tool"
127
+ },
128
+ "mcp_session": {
129
+ "type": "string",
130
+ "description": "MCP session identifier for audit trail"
131
+ }
132
+ }
133
+ },
134
+ "evaluation_rules_version": "1.0",
135
+ "evaluation_rules": [
136
+ {
137
+ "name": "tool_type_allowed",
138
+ "type": "expression",
139
+ "condition": "!limits.allowed_tool_types || limits.allowed_tool_types.includes(context.tool_type)",
140
+ "deny_code": "oap.tool_type_not_allowed",
141
+ "description": "Tool type must be in allowed list"
142
+ },
143
+ {
144
+ "name": "naming_convention",
145
+ "type": "custom_validator",
146
+ "validator": "validateToolNaming",
147
+ "deny_code": "oap.invalid_tool_name",
148
+ "description": "Tool name must follow naming convention"
149
+ },
150
+ {
151
+ "name": "tool_name_unique",
152
+ "type": "custom_validator",
153
+ "validator": "validateToolUniqueness",
154
+ "deny_code": "oap.tool_already_exists",
155
+ "description": "Tool name must be unique"
156
+ },
157
+ {
158
+ "name": "capability_validation",
159
+ "type": "custom_validator",
160
+ "validator": "validateToolCapabilities",
161
+ "deny_code": "oap.capability_not_allowed",
162
+ "description": "All tool capabilities must be allowed"
163
+ }
164
+ ],
165
+ "cache": {
166
+ "default_ttl_seconds": 300,
167
+ "suspend_invalidate_seconds": 60
168
+ },
169
+ "deprecation": null,
170
+ "created_at": "2026-02-14T00:00:00Z",
171
+ "updated_at": "2026-02-14T00:00:00Z"
172
+ }