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