@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,51 @@
|
|
|
1
|
+
|
|
2
|
+
## Required Context
|
|
3
|
+
|
|
4
|
+
This policy requires the following context (JSON Schema):
|
|
5
|
+
|
|
6
|
+
```json
|
|
7
|
+
{
|
|
8
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
9
|
+
"type": "object",
|
|
10
|
+
"required": [
|
|
11
|
+
"repository",
|
|
12
|
+
"version",
|
|
13
|
+
"files"
|
|
14
|
+
],
|
|
15
|
+
"properties": {
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "string",
|
|
18
|
+
"minLength": 1,
|
|
19
|
+
"description": "Repository identifier"
|
|
20
|
+
},
|
|
21
|
+
"version": {
|
|
22
|
+
"type": "string",
|
|
23
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$",
|
|
24
|
+
"description": "Semantic version number"
|
|
25
|
+
},
|
|
26
|
+
"files": {
|
|
27
|
+
"type": "array",
|
|
28
|
+
"minItems": 1,
|
|
29
|
+
"description": "List of files to be released",
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"description": {
|
|
35
|
+
"type": "string",
|
|
36
|
+
"description": "Release description"
|
|
37
|
+
},
|
|
38
|
+
"changelog": {
|
|
39
|
+
"type": "string",
|
|
40
|
+
"description": "Release changelog"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
You can also fetch this live via the discovery endpoint:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
curl -s "https://aport.io/api/policies/code.release.publish.v1?format=schema"
|
|
50
|
+
```
|
|
51
|
+
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "code.release.publish.v1",
|
|
3
|
+
"name": "Release Policy",
|
|
4
|
+
"description": "Pre-action governance for release operations. Enforces version format, file restrictions, and repository permissions.",
|
|
5
|
+
"version": "1.0.0",
|
|
6
|
+
"status": "active",
|
|
7
|
+
"requires_capabilities": ["release"],
|
|
8
|
+
"min_assurance": "L3",
|
|
9
|
+
"limits_required": [],
|
|
10
|
+
"required_fields": ["repository", "version", "files"],
|
|
11
|
+
"optional_fields": ["description", "changelog"],
|
|
12
|
+
"enforcement": {
|
|
13
|
+
"version_format_enforced": true,
|
|
14
|
+
"file_restrictions_enforced": true,
|
|
15
|
+
"repository_permissions_enforced": true
|
|
16
|
+
},
|
|
17
|
+
"mcp": {
|
|
18
|
+
"require_allowlisted_if_present": true
|
|
19
|
+
},
|
|
20
|
+
"advice": [
|
|
21
|
+
"Use semantic versioning for all releases",
|
|
22
|
+
"Restrict file types to prevent malicious uploads",
|
|
23
|
+
"Verify repository permissions before allowing releases",
|
|
24
|
+
"Log all release attempts for audit compliance",
|
|
25
|
+
"Subscribe to status webhooks for instant suspend"
|
|
26
|
+
],
|
|
27
|
+
"required_context": {
|
|
28
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
29
|
+
"type": "object",
|
|
30
|
+
"required": ["repository", "version", "files"],
|
|
31
|
+
"properties": {
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "string",
|
|
34
|
+
"minLength": 1,
|
|
35
|
+
"description": "Repository identifier"
|
|
36
|
+
},
|
|
37
|
+
"version": {
|
|
38
|
+
"type": "string",
|
|
39
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+(-[a-zA-Z0-9.-]+)?(\\+[a-zA-Z0-9.-]+)?$",
|
|
40
|
+
"description": "Semantic version number"
|
|
41
|
+
},
|
|
42
|
+
"files": {
|
|
43
|
+
"type": "array",
|
|
44
|
+
"minItems": 1,
|
|
45
|
+
"description": "List of files to be released",
|
|
46
|
+
"items": {
|
|
47
|
+
"type": "string"
|
|
48
|
+
}
|
|
49
|
+
},
|
|
50
|
+
"description": {
|
|
51
|
+
"type": "string",
|
|
52
|
+
"description": "Release description"
|
|
53
|
+
},
|
|
54
|
+
"changelog": {
|
|
55
|
+
"type": "string",
|
|
56
|
+
"description": "Release changelog"
|
|
57
|
+
},
|
|
58
|
+
"mcp_servers": {
|
|
59
|
+
"type": "array",
|
|
60
|
+
"items": { "type": "string" },
|
|
61
|
+
"description": "MCP servers being used in this request (e.g., [\"https://mcp.github.com\"])"
|
|
62
|
+
},
|
|
63
|
+
"mcp_tools": {
|
|
64
|
+
"type": "array",
|
|
65
|
+
"items": { "type": "string" },
|
|
66
|
+
"description": "MCP tools being used in this request (e.g., [\"github.releases.create\"])"
|
|
67
|
+
},
|
|
68
|
+
"mcp_server": {
|
|
69
|
+
"type": "string",
|
|
70
|
+
"description": "Single MCP server being used (backward compatibility - use mcp_servers array for multiple)"
|
|
71
|
+
},
|
|
72
|
+
"mcp_tool": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"description": "Single MCP tool being used (backward compatibility - use mcp_tools array for multiple)"
|
|
75
|
+
},
|
|
76
|
+
"mcp_session": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "MCP session identifier for audit trail (optional)"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"evaluation_rules": [
|
|
83
|
+
{
|
|
84
|
+
"name": "passport_status_active",
|
|
85
|
+
"condition": "passport.status == 'active'",
|
|
86
|
+
"deny_code": "oap.passport_suspended",
|
|
87
|
+
"description": "Passport must be active"
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
"name": "assurance_minimum",
|
|
91
|
+
"condition": "passport.assurance_level >= 'L3'",
|
|
92
|
+
"deny_code": "oap.assurance_insufficient",
|
|
93
|
+
"description": "Assurance level must be L3 or higher"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"name": "version_format_valid",
|
|
97
|
+
"condition": "version matches semantic versioning pattern",
|
|
98
|
+
"deny_code": "oap.format_unsupported",
|
|
99
|
+
"description": "Version must follow semantic versioning"
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
"name": "file_extensions_allowed",
|
|
103
|
+
"condition": "all files have allowed extensions",
|
|
104
|
+
"deny_code": "oap.file_forbidden",
|
|
105
|
+
"description": "All files must have allowed extensions"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"name": "repository_permission",
|
|
109
|
+
"condition": "agent has release permission for repository",
|
|
110
|
+
"deny_code": "oap.unknown_capability",
|
|
111
|
+
"description": "Agent must have release permission for repository"
|
|
112
|
+
}
|
|
113
|
+
],
|
|
114
|
+
"cache": {
|
|
115
|
+
"default_ttl_seconds": 300,
|
|
116
|
+
"suspend_invalidate_seconds": 30
|
|
117
|
+
},
|
|
118
|
+
"deprecation": null,
|
|
119
|
+
"created_at": "2025-01-30T00:00:00Z",
|
|
120
|
+
"updated_at": "2025-01-30T00:00:00Z"
|
|
121
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
# Repository Policy Pack v1
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
The `code.repository.merge.v1` policy pack protects repository operations with PR limits, merge controls, and path restrictions. This provides dev-first PR safety controls to prevent spammy or oversized PRs from agents while enabling legitimate code automation.
|
|
6
|
+
|
|
7
|
+
## Policy Requirements
|
|
8
|
+
|
|
9
|
+
| **Requirement** | **Value** | **Description** |
|
|
10
|
+
|-----------------|-----------|-----------------|
|
|
11
|
+
| **Capability** | `repo.pr.create`, `repo.merge` | Agent must have repository capabilities |
|
|
12
|
+
| **Assurance** | L2+ (GitHub Verified) | Minimum assurance level required |
|
|
13
|
+
| **Limits** | PR/merge daily caps, size limits | Required operational limits |
|
|
14
|
+
|
|
15
|
+
## Limits Configuration
|
|
16
|
+
|
|
17
|
+
### Required Limits
|
|
18
|
+
|
|
19
|
+
- **`max_prs_per_day`**: Maximum PRs created per day (1-100)
|
|
20
|
+
- **`max_merges_per_day`**: Maximum merges per day (1-100)
|
|
21
|
+
- **`max_pr_size_kb`**: Maximum PR size in KB (1-10240)
|
|
22
|
+
|
|
23
|
+
### PR Creation Parameters
|
|
24
|
+
|
|
25
|
+
- **`allowed_repos`**: Comma-separated list of allowed repositories
|
|
26
|
+
- **`allowed_base_branches`**: Comma-separated list of allowed base branches (main, develop)
|
|
27
|
+
- **`path_allowlist`**: Comma-separated list of allowed file paths/patterns
|
|
28
|
+
- **`max_files_changed`**: Maximum number of files that can be changed in one PR
|
|
29
|
+
- **`max_total_added_lines`**: Maximum total lines that can be added in one PR
|
|
30
|
+
|
|
31
|
+
### Merge Parameters
|
|
32
|
+
|
|
33
|
+
- **`allowed_repos`**: Comma-separated list of allowed repositories for merging
|
|
34
|
+
- **`allowed_base_branches`**: Comma-separated list of allowed base branches for merging
|
|
35
|
+
- **`required_labels`**: Comma-separated list of required PR labels for merging
|
|
36
|
+
- **`required_reviews`**: Minimum number of required reviews for merging
|
|
37
|
+
- **`path_allowlist`**: Comma-separated list of allowed file paths for merging
|
|
38
|
+
|
|
39
|
+
## Example Usage
|
|
40
|
+
|
|
41
|
+
### Express.js - PR Creation
|
|
42
|
+
|
|
43
|
+
```javascript
|
|
44
|
+
const { requirePolicy } = require("@aporthq/middleware-express");
|
|
45
|
+
|
|
46
|
+
app.post("/repo/pr", requirePolicy("code.repository.merge.v1"), async (req, res) => {
|
|
47
|
+
const { repo, base_branch, head_branch, title, files_changed } = req.body;
|
|
48
|
+
const passport = req.policyResult.passport;
|
|
49
|
+
|
|
50
|
+
// Policy automatically enforces:
|
|
51
|
+
// - Repository allowlist validation
|
|
52
|
+
// - Base branch restrictions
|
|
53
|
+
// - File count and line limits
|
|
54
|
+
// - Path allowlist checking
|
|
55
|
+
// - Daily PR limits
|
|
56
|
+
// - Assurance level (L2+)
|
|
57
|
+
|
|
58
|
+
const pr_id = await createPullRequest({
|
|
59
|
+
repo,
|
|
60
|
+
base_branch,
|
|
61
|
+
head_branch,
|
|
62
|
+
title,
|
|
63
|
+
files_changed,
|
|
64
|
+
agent_id: passport.agent_id,
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
res.json({ success: true, pr_id });
|
|
68
|
+
});
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Express.js - PR Merging
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
app.post("/repo/merge", requirePolicy("code.repository.merge.v1"), async (req, res) => {
|
|
75
|
+
const { repo, pr_id, merge_method } = req.body;
|
|
76
|
+
const passport = req.policyResult.passport;
|
|
77
|
+
|
|
78
|
+
// Policy automatically enforces:
|
|
79
|
+
// - Repository and branch allowlists
|
|
80
|
+
// - Required labels checking
|
|
81
|
+
// - Required reviews validation
|
|
82
|
+
// - PR size limits
|
|
83
|
+
// - Daily merge limits
|
|
84
|
+
|
|
85
|
+
const merge_result = await mergePullRequest({
|
|
86
|
+
repo,
|
|
87
|
+
pr_id,
|
|
88
|
+
merge_method,
|
|
89
|
+
agent_id: passport.agent_id,
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
res.json({ success: true, merge_sha: merge_result.sha });
|
|
93
|
+
});
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Policy Violations
|
|
97
|
+
|
|
98
|
+
### Repository Not Allowed
|
|
99
|
+
|
|
100
|
+
```json
|
|
101
|
+
{
|
|
102
|
+
"error": "repo_policy_violation",
|
|
103
|
+
"reason": "repository_not_allowlisted",
|
|
104
|
+
"repo": "sensitive-repo",
|
|
105
|
+
"allowed_repos": ["public-repo", "docs-repo"],
|
|
106
|
+
"upgrade_instructions": "Add 'sensitive-repo' to your passport's allowed_repos parameter"
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### PR Too Large
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"error": "repo_policy_violation",
|
|
115
|
+
"reason": "pr_size_exceeded",
|
|
116
|
+
"size_kb": 2048,
|
|
117
|
+
"limit_kb": 1024,
|
|
118
|
+
"files_changed": 45,
|
|
119
|
+
"lines_added": 1500
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Insufficient Reviews
|
|
124
|
+
|
|
125
|
+
```json
|
|
126
|
+
{
|
|
127
|
+
"error": "repo_policy_violation",
|
|
128
|
+
"reason": "insufficient_reviews",
|
|
129
|
+
"required_reviews": 2,
|
|
130
|
+
"current_reviews": 1,
|
|
131
|
+
"required_labels": ["approved", "security-reviewed"],
|
|
132
|
+
"missing_labels": ["security-reviewed"]
|
|
133
|
+
}
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Daily Limit Exceeded
|
|
137
|
+
|
|
138
|
+
```json
|
|
139
|
+
{
|
|
140
|
+
"error": "repo_policy_violation",
|
|
141
|
+
"reason": "daily_limit_exceeded",
|
|
142
|
+
"limit_type": "pr_creation",
|
|
143
|
+
"current_usage": 10,
|
|
144
|
+
"limit": 10,
|
|
145
|
+
"reset_time": "2025-01-17T00:00:00Z"
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Best Practices
|
|
150
|
+
|
|
151
|
+
### PR Creation
|
|
152
|
+
|
|
153
|
+
1. **Repository Allowlists**: Restrict access to specific repositories
|
|
154
|
+
2. **Branch Protection**: Limit PRs to specific base branches (main, develop)
|
|
155
|
+
3. **Size Limits**: Prevent oversized PRs that are hard to review
|
|
156
|
+
4. **Path Restrictions**: Use path allowlists to restrict file access
|
|
157
|
+
5. **Rate Limiting**: Prevent PR spam with daily limits
|
|
158
|
+
|
|
159
|
+
### Merging
|
|
160
|
+
|
|
161
|
+
1. **Review Requirements**: Enforce minimum review counts
|
|
162
|
+
2. **Label Requirements**: Require specific labels (approved, tested)
|
|
163
|
+
3. **Branch Protection**: Protect critical branches (main, production)
|
|
164
|
+
4. **Size Validation**: Ensure PRs aren't too large to review safely
|
|
165
|
+
5. **Verifiable Attestation**: Log all merge operations
|
|
166
|
+
|
|
167
|
+
### Security
|
|
168
|
+
|
|
169
|
+
1. **Protected Branches**: Use L3 assurance for production merges
|
|
170
|
+
2. **Code Review**: Always require human review for merges
|
|
171
|
+
3. **Path Restrictions**: Prevent access to sensitive files/directories
|
|
172
|
+
4. **Webhook Integration**: Subscribe to status webhooks for instant suspend
|
|
173
|
+
5. **Verifiable Attestation**: Comprehensive logging of all repository operations
|
|
174
|
+
|
|
175
|
+
### GitHub Integration
|
|
176
|
+
|
|
177
|
+
```javascript
|
|
178
|
+
// Example GitHub-specific implementation
|
|
179
|
+
async function createPullRequest({ repo, base_branch, head_branch, title, files_changed, agent_id }) {
|
|
180
|
+
const octokit = new Octokit({ auth: process.env.GITHUB_TOKEN });
|
|
181
|
+
|
|
182
|
+
const pr = await octokit.rest.pulls.create({
|
|
183
|
+
owner: "your-org",
|
|
184
|
+
repo: repo,
|
|
185
|
+
title: title,
|
|
186
|
+
head: head_branch,
|
|
187
|
+
base: base_branch,
|
|
188
|
+
body: `Created by AI Agent ${agent_id}\n\nFiles changed: ${files_changed.length}`,
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
return pr.data.number;
|
|
192
|
+
}
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Why This Policy Pack?
|
|
196
|
+
|
|
197
|
+
- **Developer Safety**: Prevents spammy or oversized PRs that harm code quality
|
|
198
|
+
- **Production Ready**: Serious governance controls for production environments
|
|
199
|
+
- **GitHub Demo**: Perfect for demonstrating AI code automation with safety
|
|
200
|
+
- **Scalable**: Works with any Git platform (GitHub, GitLab, Bitbucket)
|
|
201
|
+
- **Compliance**: Built-in Verifiable Attestation and approval workflows
|
|
202
|
+
|
|
203
|
+
## Integration Examples
|
|
204
|
+
|
|
205
|
+
- **Code Generation**: AI agents creating PRs with safety limits
|
|
206
|
+
- **Documentation Updates**: Automated doc updates with review requirements
|
|
207
|
+
- **Dependency Updates**: Automated dependency PRs with size limits
|
|
208
|
+
- **Bug Fixes**: AI-generated bug fixes with human review
|
|
209
|
+
- **Feature Development**: Controlled AI feature development with governance
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
## Required Context
|
|
213
|
+
|
|
214
|
+
This policy requires the following context (JSON Schema):
|
|
215
|
+
|
|
216
|
+
```json
|
|
217
|
+
{
|
|
218
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
219
|
+
"type": "object",
|
|
220
|
+
"required": [
|
|
221
|
+
"repository",
|
|
222
|
+
"action",
|
|
223
|
+
"branch"
|
|
224
|
+
],
|
|
225
|
+
"properties": {
|
|
226
|
+
"repository": {
|
|
227
|
+
"type": "string",
|
|
228
|
+
"pattern": "^[a-zA-Z0-9._-]+/[a-zA-Z0-9._-]+$",
|
|
229
|
+
"description": "Repository in owner/repo format"
|
|
230
|
+
},
|
|
231
|
+
"action": {
|
|
232
|
+
"type": "string",
|
|
233
|
+
"enum": [
|
|
234
|
+
"pr.create",
|
|
235
|
+
"pr.merge",
|
|
236
|
+
"pr.update",
|
|
237
|
+
"branch.create",
|
|
238
|
+
"branch.delete"
|
|
239
|
+
],
|
|
240
|
+
"description": "Repository action being performed"
|
|
241
|
+
},
|
|
242
|
+
"branch": {
|
|
243
|
+
"type": "string",
|
|
244
|
+
"minLength": 1,
|
|
245
|
+
"description": "Target branch name"
|
|
246
|
+
},
|
|
247
|
+
"base_branch": {
|
|
248
|
+
"type": "string",
|
|
249
|
+
"description": "Base branch for PR operations"
|
|
250
|
+
},
|
|
251
|
+
"title": {
|
|
252
|
+
"type": "string",
|
|
253
|
+
"maxLength": 200,
|
|
254
|
+
"description": "PR or commit title"
|
|
255
|
+
},
|
|
256
|
+
"description": {
|
|
257
|
+
"type": "string",
|
|
258
|
+
"maxLength": 5000,
|
|
259
|
+
"description": "PR or commit description"
|
|
260
|
+
},
|
|
261
|
+
"files_changed": {
|
|
262
|
+
"type": "array",
|
|
263
|
+
"items": {
|
|
264
|
+
"type": "string"
|
|
265
|
+
},
|
|
266
|
+
"description": "List of files being changed"
|
|
267
|
+
},
|
|
268
|
+
"lines_added": {
|
|
269
|
+
"type": "integer",
|
|
270
|
+
"minimum": 0,
|
|
271
|
+
"description": "Number of lines added"
|
|
272
|
+
},
|
|
273
|
+
"lines_removed": {
|
|
274
|
+
"type": "integer",
|
|
275
|
+
"minimum": 0,
|
|
276
|
+
"description": "Number of lines removed"
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
You can also fetch this live via the discovery endpoint:
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
curl -s "https://aport.io/api/policies/code.repository.merge.v1?format=schema"
|
|
286
|
+
```
|
|
287
|
+
|