@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.
- package/LICENSE +217 -0
- package/README.md +481 -0
- package/bin/agent-guardrails +133 -0
- package/bin/aport-create-passport.sh +444 -0
- package/bin/aport-cursor-hook.sh +90 -0
- package/bin/aport-guardrail-api.sh +108 -0
- package/bin/aport-guardrail-bash.sh +394 -0
- package/bin/aport-guardrail-v2.sh +5 -0
- package/bin/aport-guardrail.sh +5 -0
- package/bin/aport-resolve-paths.sh +71 -0
- package/bin/aport-status.sh +276 -0
- package/bin/frameworks/crewai.sh +49 -0
- package/bin/frameworks/cursor.sh +95 -0
- package/bin/frameworks/langchain.sh +48 -0
- package/bin/frameworks/n8n.sh +36 -0
- package/bin/frameworks/openclaw.sh +19 -0
- package/bin/lib/allowlist.sh +18 -0
- package/bin/lib/common.sh +28 -0
- package/bin/lib/config.sh +46 -0
- package/bin/lib/constants.sh +232 -0
- package/bin/lib/detect.sh +65 -0
- package/bin/lib/error.sh +269 -0
- package/bin/lib/passport.sh +19 -0
- package/bin/lib/templates/.gitkeep +1 -0
- package/bin/lib/templates/config.yaml +6 -0
- package/bin/lib/validation.sh +206 -0
- package/bin/openclaw +660 -0
- package/docs/ADDING_A_FRAMEWORK.md +87 -0
- package/docs/AGENTS.md.example +40 -0
- package/docs/CODE_REVIEW.md +192 -0
- package/docs/DEPLOYMENT_READINESS.md +81 -0
- package/docs/FAQ_SECURITY_SCANNERS.md +373 -0
- package/docs/FRAMEWORK_ROADMAP.md +41 -0
- package/docs/HOSTED_PASSPORT_SETUP.md +362 -0
- package/docs/IMPLEMENTING_YOUR_OWN_EVALUATOR.md +433 -0
- package/docs/OPENCLAW_COMPATIBILITY.md +73 -0
- package/docs/OPENCLAW_LOCAL_INTEGRATION.md +596 -0
- package/docs/OPENCLAW_TOOLS_AND_POLICIES.md +54 -0
- package/docs/QUICKSTART.md +470 -0
- package/docs/QUICKSTART_OPENCLAW_PLUGIN.md +470 -0
- package/docs/README.md +28 -0
- package/docs/RELEASE.md +87 -0
- package/docs/REPO_LAYOUT.md +47 -0
- package/docs/SKILLS_ECOSYSTEM_ANALYSIS_FEB17.md +1260 -0
- package/docs/TOOL_POLICY_MAPPING.md +46 -0
- package/docs/UPGRADE.md +46 -0
- package/docs/VERIFICATION_METHODS.md +97 -0
- package/docs/assets/README.md +8 -0
- package/docs/assets/porter.svg +54 -0
- package/docs/development/ERROR_CODES.md +616 -0
- package/docs/frameworks/GITHUB_ISSUE_PROPOSALS.md +1105 -0
- package/docs/frameworks/crewai.md +114 -0
- package/docs/frameworks/cursor.md +159 -0
- package/docs/frameworks/langchain.md +72 -0
- package/docs/frameworks/n8n.md +40 -0
- package/docs/frameworks/openclaw.md +40 -0
- package/docs/launch/ADD_APORT_AWESOME_LISTS_INSTRUCTIONS.md +146 -0
- package/docs/launch/ANNOUNCEMENT_GUIDE.md +266 -0
- package/docs/launch/AWESOME_REPOS.md +53 -0
- package/docs/launch/CURSOR_VSCODE_HOOKS_RESEARCH.md +77 -0
- package/docs/launch/DEMO_TERMINAL_OUTPUT.txt +48 -0
- package/docs/launch/DRY_AND_PLAN_CHECKLIST.md +47 -0
- package/docs/launch/EVIDENCE_README.md +61 -0
- package/docs/launch/EVIDENCE_TERMINAL_CAPTURE.txt +10 -0
- package/docs/launch/FRAMEWORK_SUPPORT_PLAN.md +1640 -0
- package/docs/launch/LAUNCH_READINESS_CHECKLIST.md +237 -0
- package/docs/launch/LAUNCH_STRATEGY_SUMMARY.md +464 -0
- package/docs/launch/OPENCLAW_FEEDBACK_AND_FIXES.md +85 -0
- package/docs/launch/POST_1_VALENTINE_IMPROVED.md +233 -0
- package/docs/launch/POST_2_GUARDRAIL_IMPROVED.md +369 -0
- package/docs/launch/PRE_LAUNCH_FIXES.md +766 -0
- package/docs/launch/QUICK_LAUNCH_CHECKLIST.md +400 -0
- package/docs/launch/READINESS_SUMMARY.md +262 -0
- package/docs/launch/README.md +68 -0
- package/docs/launch/USER_STORIES.md +327 -0
- package/docs/launch/scripts/add-aport-awesome-pr.sh +69 -0
- package/docs/operations/MONITORING.md +588 -0
- package/docs/reviews/2026-02-18-staff-review.md +268 -0
- package/extensions/openclaw-aport/README.md +415 -0
- package/extensions/openclaw-aport/index.js +625 -0
- package/extensions/openclaw-aport/openclaw-aport.js +7 -0
- package/extensions/openclaw-aport/openclaw.plugin.json +46 -0
- package/extensions/openclaw-aport/package.json +36 -0
- package/extensions/openclaw-aport/test.js +307 -0
- package/external/aport-policies/README.md +363 -0
- package/external/aport-policies/agent.session.create.v1/README.md +345 -0
- package/external/aport-policies/agent.session.create.v1/policy.json +162 -0
- package/external/aport-policies/agent.tool.register.v1/README.md +361 -0
- package/external/aport-policies/agent.tool.register.v1/policy.json +172 -0
- package/external/aport-policies/code.release.publish.v1/README.md +51 -0
- package/external/aport-policies/code.release.publish.v1/policy.json +121 -0
- package/external/aport-policies/code.repository.merge.v1/README.md +287 -0
- package/external/aport-policies/code.repository.merge.v1/express.example.js +332 -0
- package/external/aport-policies/code.repository.merge.v1/fastapi.example.py +370 -0
- package/external/aport-policies/code.repository.merge.v1/policy.json +162 -0
- package/external/aport-policies/data.export.create.v1/README.md +226 -0
- package/external/aport-policies/data.export.create.v1/express.example.js +172 -0
- package/external/aport-policies/data.export.create.v1/fastapi.example.py +165 -0
- package/external/aport-policies/data.export.create.v1/policy.json +133 -0
- package/external/aport-policies/data.report.ingest.v1/README.md +134 -0
- package/external/aport-policies/data.report.ingest.v1/express.example.js +105 -0
- package/external/aport-policies/data.report.ingest.v1/minimal-example.js +68 -0
- package/external/aport-policies/data.report.ingest.v1/policy.json +174 -0
- package/external/aport-policies/finance.crypto.trade.v1/README.md +146 -0
- package/external/aport-policies/finance.crypto.trade.v1/express.example.js +109 -0
- package/external/aport-policies/finance.crypto.trade.v1/minimal-example.js +65 -0
- package/external/aport-policies/finance.crypto.trade.v1/policy.json +176 -0
- package/external/aport-policies/finance.payment.charge.v1/README.md +326 -0
- package/external/aport-policies/finance.payment.charge.v1/express.example.js +250 -0
- package/external/aport-policies/finance.payment.charge.v1/fastapi.example.py +227 -0
- package/external/aport-policies/finance.payment.charge.v1/minimal-example.js +64 -0
- package/external/aport-policies/finance.payment.charge.v1/policy.json +224 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/contexts.jsonl +12 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/expected.jsonl +12 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/passport.instance.json +42 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/passport.template.json +40 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/payments-charge-policy.test.js +817 -0
- package/external/aport-policies/finance.payment.charge.v1/tests/test_payments_charge_policy.py +486 -0
- package/external/aport-policies/finance.payment.payout.v1/README.md +78 -0
- package/external/aport-policies/finance.payment.payout.v1/policy.json +181 -0
- package/external/aport-policies/finance.payment.refund.v1/README.md +275 -0
- package/external/aport-policies/finance.payment.refund.v1/express.example.js +167 -0
- package/external/aport-policies/finance.payment.refund.v1/fastapi.example.py +136 -0
- package/external/aport-policies/finance.payment.refund.v1/minimal-example.js +183 -0
- package/external/aport-policies/finance.payment.refund.v1/policy.json +216 -0
- package/external/aport-policies/finance.payment.refund.v1/tests/refunds-policy.test.js +924 -0
- package/external/aport-policies/finance.payment.refund.v1/tests/test_refunds_policy.py +778 -0
- package/external/aport-policies/finance.transaction.execute.v1/README.md +309 -0
- package/external/aport-policies/finance.transaction.execute.v1/express.example.js +261 -0
- package/external/aport-policies/finance.transaction.execute.v1/fastapi.example.py +231 -0
- package/external/aport-policies/finance.transaction.execute.v1/minimal-example.js +78 -0
- package/external/aport-policies/finance.transaction.execute.v1/policy.json +189 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/contexts.jsonl +12 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/expected.jsonl +12 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/passport.instance.json +42 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/passport.template.json +42 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/test_transactions_policy.py +214 -0
- package/external/aport-policies/finance.transaction.execute.v1/tests/transactions-policy.test.js +306 -0
- package/external/aport-policies/governance.data.access.v1/README.md +292 -0
- package/external/aport-policies/governance.data.access.v1/express.example.js +321 -0
- package/external/aport-policies/governance.data.access.v1/fastapi.example.py +279 -0
- package/external/aport-policies/governance.data.access.v1/minimal-example.js +65 -0
- package/external/aport-policies/governance.data.access.v1/policy.json +208 -0
- package/external/aport-policies/governance.data.access.v1/tests/contexts.jsonl +12 -0
- package/external/aport-policies/governance.data.access.v1/tests/data-access-policy.test.js +308 -0
- package/external/aport-policies/governance.data.access.v1/tests/expected.jsonl +12 -0
- package/external/aport-policies/governance.data.access.v1/tests/passport.instance.json +56 -0
- package/external/aport-policies/governance.data.access.v1/tests/passport.template.json +56 -0
- package/external/aport-policies/governance.data.access.v1/tests/test_data_access_policy.py +214 -0
- package/external/aport-policies/legal.contract.review.v1/README.md +109 -0
- package/external/aport-policies/legal.contract.review.v1/policy.json +378 -0
- package/external/aport-policies/legal.contract.review.v1/tests/legal-contract-review-policy.test.js +609 -0
- package/external/aport-policies/legal.contract.review.v1/tests/passport.template.json +49 -0
- package/external/aport-policies/mcp.tool.execute.v1/README.md +301 -0
- package/external/aport-policies/mcp.tool.execute.v1/policy.json +141 -0
- package/external/aport-policies/messaging.message.send.v1/README.md +230 -0
- package/external/aport-policies/messaging.message.send.v1/express.example.js +183 -0
- package/external/aport-policies/messaging.message.send.v1/fastapi.example.py +193 -0
- package/external/aport-policies/messaging.message.send.v1/policy.json +144 -0
- package/external/aport-policies/policy-template.json +107 -0
- package/external/aport-policies/system.command.execute.v1/README.md +275 -0
- package/external/aport-policies/system.command.execute.v1/policy.json +146 -0
- package/external/aport-spec/CONTRIBUTING.md +273 -0
- package/external/aport-spec/LICENSE +21 -0
- package/external/aport-spec/README.md +168 -0
- package/external/aport-spec/conformance/README.md +294 -0
- package/external/aport-spec/conformance/cases/data.export.v1/contexts/allow_users.json +6 -0
- package/external/aport-spec/conformance/cases/data.export.v1/contexts/deny_pii.json +6 -0
- package/external/aport-spec/conformance/cases/data.export.v1/expected/allow_users.decision.json +19 -0
- package/external/aport-spec/conformance/cases/data.export.v1/expected/deny_pii.decision.json +19 -0
- package/external/aport-spec/conformance/cases/data.export.v1/passports/template.json +29 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/allow_50usd.json +9 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_150usd.json +9 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/contexts/deny_currency.json +9 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/allow_50usd.decision.json +19 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_150usd.decision.json +19 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/expected/deny_currency.decision.json +19 -0
- package/external/aport-spec/conformance/cases/payments.refunds.v1/passports/template.json +42 -0
- package/external/aport-spec/conformance/package.json +44 -0
- package/external/aport-spec/conformance/pnpm-lock.yaml +642 -0
- package/external/aport-spec/conformance/src/cases.ts +371 -0
- package/external/aport-spec/conformance/src/ed25519.ts +167 -0
- package/external/aport-spec/conformance/src/jcs.ts +85 -0
- package/external/aport-spec/conformance/src/runner.ts +533 -0
- package/external/aport-spec/conformance/src/validators.ts +185 -0
- package/external/aport-spec/conformance/test-runner.js +315 -0
- package/external/aport-spec/conformance/tsconfig.json +21 -0
- package/external/aport-spec/error-schema.json +192 -0
- package/external/aport-spec/index.json +12 -0
- package/external/aport-spec/integrations/clawmoat/README.md +12 -0
- package/external/aport-spec/integrations/shield/README.md +245 -0
- package/external/aport-spec/integrations/shield/adapters/index.js +116 -0
- package/external/aport-spec/integrations/shield/adapters/system-command-execute.js +133 -0
- package/external/aport-spec/integrations/shield/test/README.md +58 -0
- package/external/aport-spec/integrations/shield/test/shield.md +40 -0
- package/external/aport-spec/integrations/shield/test/test-shield-to-verify.js +274 -0
- package/external/aport-spec/metrics-schema.json +504 -0
- package/external/aport-spec/oap/CHANGELOG.md +54 -0
- package/external/aport-spec/oap/VERSION.md +40 -0
- package/external/aport-spec/oap/capability-registry.md +229 -0
- package/external/aport-spec/oap/conformance.md +257 -0
- package/external/aport-spec/oap/decision-schema.json +114 -0
- package/external/aport-spec/oap/examples/context.refund.usd.50.json +9 -0
- package/external/aport-spec/oap/examples/decision.allow.sample.json +20 -0
- package/external/aport-spec/oap/examples/decision.deny.sample.json +23 -0
- package/external/aport-spec/oap/examples/passport.instance.v1.json +50 -0
- package/external/aport-spec/oap/examples/passport.template.v1.json +71 -0
- package/external/aport-spec/oap/oap-spec.md +426 -0
- package/external/aport-spec/oap/passport-schema.json +396 -0
- package/external/aport-spec/oap/security.md +213 -0
- package/external/aport-spec/oap/vc/context-oap-v1.jsonld +137 -0
- package/external/aport-spec/oap/vc/examples/oap-decision-vc.json +37 -0
- package/external/aport-spec/oap/vc/examples/oap-passport-vc.json +68 -0
- package/external/aport-spec/oap/vc/tools/INTEGRATION.md +375 -0
- package/external/aport-spec/oap/vc/tools/README.md +278 -0
- package/external/aport-spec/oap/vc/tools/examples/decision-to-vc.js +66 -0
- package/external/aport-spec/oap/vc/tools/examples/passport-to-vc.js +83 -0
- package/external/aport-spec/oap/vc/tools/examples/vc-to-decision.js +77 -0
- package/external/aport-spec/oap/vc/tools/examples/vc-to-passport.js +94 -0
- package/external/aport-spec/oap/vc/tools/package.json +38 -0
- package/external/aport-spec/oap/vc/tools/pnpm-lock.yaml +472 -0
- package/external/aport-spec/oap/vc/tools/src/cli.ts +226 -0
- package/external/aport-spec/oap/vc/tools/src/crypto-utils.ts +427 -0
- package/external/aport-spec/oap/vc/tools/src/index.ts +653 -0
- package/external/aport-spec/oap/vc/tools/src/test.ts +148 -0
- package/external/aport-spec/oap/vc/tools/src/vp.ts +382 -0
- package/external/aport-spec/oap/vc/tools/test-simple.js +214 -0
- package/external/aport-spec/oap/vc/tools/tsconfig.json +19 -0
- package/external/aport-spec/oap/vc/vc-mapping.md +443 -0
- package/external/aport-spec/passport-schema.json +586 -0
- package/external/aport-spec/rate-limiting.md +136 -0
- package/external/aport-spec/transport-profile.md +325 -0
- package/external/aport-spec/webhook-spec.md +314 -0
- package/package.json +70 -0
- package/skills/aport-agent-guardrail/SKILL.md +314 -0
- package/src/evaluator.js +252 -0
- 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
|
+
}
|