@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,470 @@
|
|
|
1
|
+
# Quick Start Guide
|
|
2
|
+
**Get started with APort Agent Guardrails in 5 minutes**
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Recommended: one command (npm, no clone)
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npx @aporthq/aport-agent-guardrails
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
If you have an agent_id from aport.io, run `npx @aporthq/aport-agent-guardrails <agent_id>` to use a hosted passport (no local file). See [HOSTED_PASSPORT_SETUP.md](HOSTED_PASSPORT_SETUP.md).
|
|
13
|
+
|
|
14
|
+
This uses the [npm package](https://www.npmjs.com/package/@aporthq/aport-agent-guardrails): downloads the package, runs the setup wizard, installs the plugin and wrappers, and runs a smoke test.
|
|
15
|
+
|
|
16
|
+
**Alternative: from the repo** (if you cloned the repo):
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
make openclaw-setup
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
./bin/openclaw
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The script will:
|
|
29
|
+
|
|
30
|
+
1. **Prompt for your OpenClaw config directory** — default `~/.openclaw`; you can use a different path (e.g. your project’s `.openclaw`).
|
|
31
|
+
2. **Run the passport wizard** — guided by the OAP spec (`external/aport-spec`); you choose capabilities and limits.
|
|
32
|
+
3. **Install wrappers** in your config dir (`.skills/`) so OpenClaw can call the guardrail with the correct passport/decision paths.
|
|
33
|
+
4. **Update your passport** — the installer sets `allowed_commands: ["*"]` automatically (no manual editing needed); then runs a self-check and exits with a clear error if the check is denied.
|
|
34
|
+
5. **Install the APort skill** in `~/.openclaw/skills/aport-guardrail/` so OpenClaw loads it; the agent knows to call the guardrail before effectful actions.
|
|
35
|
+
6. **Print the tool → policy mapping** so you see how tool names map to policy packs in `external/aport-policies`. Full table: [TOOL_POLICY_MAPPING.md](TOOL_POLICY_MAPPING.md). If you have a workspace, the script saves an AGENTS.md snippet you can merge.
|
|
36
|
+
|
|
37
|
+
Then test with the path it showed (e.g. `~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"ls"}'`).
|
|
38
|
+
|
|
39
|
+
For **OpenClaw + API** (self-hosted or cloud), see [OpenClaw Local Integration](OPENCLAW_LOCAL_INTEGRATION.md).
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## Copy-paste (no wizard)
|
|
44
|
+
|
|
45
|
+
If you prefer a single block with no prompts (e.g. for automation or a different config dir):
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
git clone https://github.com/aporthq/aport-agent-guardrails.git && cd aport-agent-guardrails
|
|
49
|
+
mkdir -p ~/.openclaw
|
|
50
|
+
# Create minimal passport (see README for full JSON)
|
|
51
|
+
make install
|
|
52
|
+
~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"ls"}'
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Note: `make install` copies scripts to `~/.openclaw/.skills`; the guardrail will look for policies in the **repo** (so run from repo or use `./bin/openclaw` for path-aware wrappers that point to the repo).
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## Prerequisites
|
|
60
|
+
|
|
61
|
+
- `jq` (`brew install jq` on macOS)
|
|
62
|
+
- Bash shell
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Step 1: Install (if not using openclaw script)
|
|
67
|
+
|
|
68
|
+
From the repo root:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
make install
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This copies scripts to `~/.openclaw/.skills/`. For a **configurable path** and wrappers that always use this repo’s policies, use `./bin/openclaw` instead.
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## Step 2: Create Your First Passport (1 minute)
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
~/.openclaw/.skills/aport-create-passport.sh
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Interactive prompts will guide you through:**
|
|
85
|
+
1. Your email/ID (e.g., `uchi@aport.io`)
|
|
86
|
+
2. Owner type (user/team/org) - Choose `user`
|
|
87
|
+
3. Capabilities:
|
|
88
|
+
- Create and merge PRs? → `y`
|
|
89
|
+
- Execute system commands? → `y`
|
|
90
|
+
- Send messages? → `n` (for now)
|
|
91
|
+
- Export data? → `n` (for now)
|
|
92
|
+
4. Limits:
|
|
93
|
+
- Max PR size: `500` (files)
|
|
94
|
+
- Max PRs per day: `10`
|
|
95
|
+
- Allowed repos: `*` (all repos)
|
|
96
|
+
|
|
97
|
+
**Result:** Passport created at `~/.openclaw/passport.json`
|
|
98
|
+
|
|
99
|
+
**Verify:**
|
|
100
|
+
```bash
|
|
101
|
+
cat ~/.openclaw/passport.json | jq '.passport_id, .status, .expires_at'
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
You should see:
|
|
105
|
+
```json
|
|
106
|
+
"550e8400-e29b-41d4-a716-446655440000"
|
|
107
|
+
"active"
|
|
108
|
+
"2026-03-16T00:00:00Z"
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## Step 3: Check Status (10 seconds)
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
~/.openclaw/.skills/aport-status.sh
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
**You'll see:**
|
|
120
|
+
```
|
|
121
|
+
🛂 APort Status Dashboard
|
|
122
|
+
=========================
|
|
123
|
+
|
|
124
|
+
🟢 Kill Switch: inactive
|
|
125
|
+
|
|
126
|
+
📋 Passport Information
|
|
127
|
+
Location: /Users/uchi/.openclaw/passport.json
|
|
128
|
+
ID: 550e8400-e29b-41d4-a716-446655440000
|
|
129
|
+
Owner: uchi@aport.io
|
|
130
|
+
Type: user
|
|
131
|
+
Status: ✅ active
|
|
132
|
+
Expires: 2026-03-16T00:00:00Z
|
|
133
|
+
✅ 30 days until expiration
|
|
134
|
+
|
|
135
|
+
🔐 Capabilities
|
|
136
|
+
• repo.pr.create
|
|
137
|
+
• repo.merge
|
|
138
|
+
• system.command.execute
|
|
139
|
+
|
|
140
|
+
⚙️ Limits
|
|
141
|
+
• code.repository.merge:
|
|
142
|
+
- Max PRs/day: 10
|
|
143
|
+
- Max PR size: 500 files
|
|
144
|
+
|
|
145
|
+
📊 Recent Activity (last 10)
|
|
146
|
+
(no activity yet)
|
|
147
|
+
|
|
148
|
+
💡 Useful Commands
|
|
149
|
+
• View full audit log: tail -f /Users/uchi/.openclaw/audit.log
|
|
150
|
+
• Edit passport: vim /Users/uchi/.openclaw/passport.json
|
|
151
|
+
• Verify passport: aport-verify-passport.sh
|
|
152
|
+
• Suspend agent (local): set passport status to "suspended" in passport.json (e.g. jq '.status = "suspended"')
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Step 4: Test Policy Evaluation (1 minute)
|
|
158
|
+
|
|
159
|
+
Scripts exit **0** = allow, **1** = deny. The decision is written to `~/.openclaw/decision.json` (not printed to stdout).
|
|
160
|
+
|
|
161
|
+
### Test 1: Allow a small PR (should PASS)
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
~/.openclaw/.skills/aport-guardrail.sh git.create_pr '{
|
|
165
|
+
"repo": "aport-agent-guardrails",
|
|
166
|
+
"branch": "feature/test",
|
|
167
|
+
"base_branch": "main",
|
|
168
|
+
"files_changed": 10
|
|
169
|
+
}'
|
|
170
|
+
echo "Exit: $? (0 = ALLOW)"
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Check decision:**
|
|
174
|
+
```bash
|
|
175
|
+
cat ~/.openclaw/decision.json | jq .
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
**Check audit log:**
|
|
179
|
+
```bash
|
|
180
|
+
tail -1 ~/.openclaw/audit.log
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
### Test 2: Deny a large PR (should FAIL)
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
~/.openclaw/.skills/aport-guardrail.sh git.create_pr '{
|
|
189
|
+
"repo": "aport-agent-guardrails",
|
|
190
|
+
"branch": "feature/large",
|
|
191
|
+
"files_changed": 1000
|
|
192
|
+
}'
|
|
193
|
+
echo "Exit: $? (1 = DENY)"
|
|
194
|
+
cat ~/.openclaw/decision.json | jq '.allow, .reasons'
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
You should see `"allow": false` and a deny reason.
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
### Test 3: Block dangerous command (should FAIL)
|
|
202
|
+
|
|
203
|
+
```bash
|
|
204
|
+
~/.openclaw/.skills/aport-guardrail.sh system.command.execute '{"command":"rm -rf /tmp/test"}'
|
|
205
|
+
echo "Exit: $? (1 = DENY)"
|
|
206
|
+
cat ~/.openclaw/decision.json | jq '.allow, .reasons[0].message'
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
---
|
|
210
|
+
|
|
211
|
+
## Step 5: Test suspend (kill switch = passport status) (30 seconds)
|
|
212
|
+
|
|
213
|
+
The passport is the source of truth. To suspend the agent, set passport `status` to `suspended`.
|
|
214
|
+
|
|
215
|
+
### Suspend the agent:
|
|
216
|
+
```bash
|
|
217
|
+
# Set passport status to suspended (e.g. edit ~/.openclaw/aport/passport.json or:)
|
|
218
|
+
jq '.status = "suspended"' ~/.openclaw/aport/passport.json > /tmp/passport.tmp && mv /tmp/passport.tmp ~/.openclaw/aport/passport.json
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Try any action (should be blocked):
|
|
222
|
+
```bash
|
|
223
|
+
~/.openclaw/.skills/aport-guardrail.sh git.create_pr '{"repo": "test", "files_changed": 1}'
|
|
224
|
+
cat ~/.openclaw/decision.json | jq '.allow, .reasons[0].code'
|
|
225
|
+
```
|
|
226
|
+
You should see `allow: false` and `oap.passport_suspended`.
|
|
227
|
+
|
|
228
|
+
### Resume the agent:
|
|
229
|
+
```bash
|
|
230
|
+
jq '.status = "active"' ~/.openclaw/aport/passport.json > /tmp/passport.tmp && mv /tmp/passport.tmp ~/.openclaw/aport/passport.json
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Verify it works again:
|
|
234
|
+
```bash
|
|
235
|
+
~/.openclaw/.skills/aport-guardrail.sh git.create_pr '{"repo": "test", "files_changed": 1}'
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Should see `"allow": true` now.
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## Step 6: View Activity Dashboard (10 seconds)
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
~/.openclaw/.skills/aport-status.sh
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**You'll now see:**
|
|
249
|
+
```
|
|
250
|
+
📊 Recent Activity (last 10)
|
|
251
|
+
✅ 2026-02-14 17:00:00 | git.create_pr
|
|
252
|
+
❌ 2026-02-14 17:01:00 | git.create_pr
|
|
253
|
+
❌ 2026-02-14 17:02:00 | exec.run
|
|
254
|
+
❌ 2026-02-14 17:03:00 | git.create_pr
|
|
255
|
+
|
|
256
|
+
📈 Statistics (all time)
|
|
257
|
+
Total actions: 4
|
|
258
|
+
Allowed: 1
|
|
259
|
+
Denied: 3
|
|
260
|
+
Allow rate: 25%
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
---
|
|
264
|
+
|
|
265
|
+
## 🎉 Success! You've tested all core features
|
|
266
|
+
|
|
267
|
+
**What you've verified:**
|
|
268
|
+
- ✅ Passport creation (interactive wizard)
|
|
269
|
+
- ✅ Status dashboard (health checks)
|
|
270
|
+
- ✅ Policy evaluation (allow/deny based on rules)
|
|
271
|
+
- ✅ Kill switch (global emergency stop)
|
|
272
|
+
- ✅ Audit logging (tamper-evident trail)
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## Step 7: Integrate with Your OpenClaw Instance (5 minutes)
|
|
277
|
+
|
|
278
|
+
### Option A: Add to AGENTS.md (Recommended)
|
|
279
|
+
|
|
280
|
+
**1. Locate your OpenClaw AGENTS.md:**
|
|
281
|
+
```bash
|
|
282
|
+
# Find your OpenClaw installation
|
|
283
|
+
find ~ -name "AGENTS.md" -path "*/.openclaw/*" | head -1
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
**2. Add APort section:** From the repo root:
|
|
287
|
+
```bash
|
|
288
|
+
cat docs/AGENTS.md.example >> ~/.openclaw/AGENTS.md
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**3. Verify:**
|
|
292
|
+
```bash
|
|
293
|
+
cat ~/.openclaw/AGENTS.md | grep "Pre-Action Authorization"
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
### Option B: Manual Integration (Advanced)
|
|
299
|
+
|
|
300
|
+
**In your OpenClaw agent code, before any tool execution:**
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
import subprocess
|
|
304
|
+
import json
|
|
305
|
+
|
|
306
|
+
def execute_tool(tool_name, params):
|
|
307
|
+
# 1. Pre-action verification
|
|
308
|
+
result = subprocess.run([
|
|
309
|
+
'~/.openclaw/.skills/aport-guardrail.sh',
|
|
310
|
+
tool_name,
|
|
311
|
+
json.dumps(params)
|
|
312
|
+
], capture_output=True, text=True)
|
|
313
|
+
|
|
314
|
+
# 2. Read decision
|
|
315
|
+
with open(os.path.expanduser('~/.openclaw/decision.json')) as f:
|
|
316
|
+
decision = json.load(f)
|
|
317
|
+
|
|
318
|
+
# 3. Check if allowed
|
|
319
|
+
if not decision.get('allow'):
|
|
320
|
+
raise PermissionError(f"Policy denied: {decision.get('message')}")
|
|
321
|
+
|
|
322
|
+
# 4. Execute tool (if allowed)
|
|
323
|
+
return actual_tool_execution(tool_name, params)
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Step 8: Customize Your Passport (Optional)
|
|
329
|
+
|
|
330
|
+
### Edit passport directly:
|
|
331
|
+
```bash
|
|
332
|
+
vim ~/.openclaw/passport.json
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
### Common customizations:
|
|
336
|
+
|
|
337
|
+
**1. Change PR size limit:**
|
|
338
|
+
```json
|
|
339
|
+
{
|
|
340
|
+
"limits": {
|
|
341
|
+
"code.repository.merge": {
|
|
342
|
+
"max_pr_size_kb": 1000 // Increase from 500 to 1000
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
**2. Add allowed repos (restrict to specific repos):**
|
|
349
|
+
```json
|
|
350
|
+
{
|
|
351
|
+
"limits": {
|
|
352
|
+
"code.repository.merge": {
|
|
353
|
+
"allowed_repos": ["aporthq/*", "my-org/*"] // Only these repos
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**3. Add blocked commands:**
|
|
360
|
+
```json
|
|
361
|
+
{
|
|
362
|
+
"limits": {
|
|
363
|
+
"system.command.execute": {
|
|
364
|
+
"blocked_patterns": ["rm -rf", "sudo", "curl | bash", "dd if="]
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**After editing, verify:**
|
|
371
|
+
```bash
|
|
372
|
+
jq . ~/.openclaw/passport.json > /dev/null && echo "✅ Valid JSON" || echo "❌ Invalid JSON"
|
|
373
|
+
```
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## Troubleshooting
|
|
378
|
+
|
|
379
|
+
### Problem: "jq not found"
|
|
380
|
+
```bash
|
|
381
|
+
brew install jq # macOS
|
|
382
|
+
apt-get install jq # Linux
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
### Problem: "Permission denied"
|
|
386
|
+
```bash
|
|
387
|
+
chmod +x ~/.openclaw/.skills/aport-*.sh
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
### Problem: "Passport not found"
|
|
391
|
+
```bash
|
|
392
|
+
# Recreate passport
|
|
393
|
+
~/.openclaw/.skills/aport-create-passport.sh
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Problem: "Command must be in allowed list" (oap.command_not_allowed)
|
|
397
|
+
The guardrail is blocking **exec** because the command (e.g. `mkdir`, `ls`) is not in your passport’s **allowed_commands**. OpenClaw uses **exec** for both guardrail invocations and real shell commands; we check real commands against the passport.
|
|
398
|
+
|
|
399
|
+
**Fix:** The installer sets `allowed_commands: ["*"]` by default; this usually appears only if you intentionally tightened the allowlist. Re-add the commands you need to `limits.system.command.execute.allowed_commands`, or set `["*"]` (blocked patterns still apply). Alternatively, set **mapExecToPolicy: false** in the plugin config so exec is never checked (no command allowlist; use only if you rely on other controls). See [OPENCLAW_TOOLS_AND_POLICIES.md](OPENCLAW_TOOLS_AND_POLICIES.md).
|
|
400
|
+
|
|
401
|
+
### Problem: "Missing required capabilities: messaging.send"
|
|
402
|
+
If you see `oap.unknown_capability: Missing required capabilities: messaging.send`, your passport was created with the old capability/limits keys. Align with APort:
|
|
403
|
+
|
|
404
|
+
- In `capabilities`, use `"id": "messaging.send"` (not `messaging.message.send`).
|
|
405
|
+
- In `limits`, use the key `"messaging"` (not `messaging.message.send`) for `msgs_per_min`, `msgs_per_day`, etc.
|
|
406
|
+
|
|
407
|
+
Re-run the passport wizard to create a new passport, or edit `~/.openclaw/passport.json` and fix those two places.
|
|
408
|
+
|
|
409
|
+
### Problem: "All actions denied"
|
|
410
|
+
```bash
|
|
411
|
+
# Check passport status (source of truth for suspend)
|
|
412
|
+
jq '.status' ~/.openclaw/aport/passport.json
|
|
413
|
+
# Should be "active"; if "suspended" or "revoked", set back to "active" to resume
|
|
414
|
+
|
|
415
|
+
# Check expiration
|
|
416
|
+
jq '.expires_at' ~/.openclaw/passport.json
|
|
417
|
+
# If expired, update it
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
### Problem: "Decision file not created"
|
|
421
|
+
```bash
|
|
422
|
+
# Check script permissions
|
|
423
|
+
ls -la ~/.openclaw/.skills/aport-guardrail.sh
|
|
424
|
+
# Should be -rwxr-xr-x (executable)
|
|
425
|
+
|
|
426
|
+
# Make executable
|
|
427
|
+
chmod +x ~/.openclaw/.skills/aport-guardrail.sh
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## Next Steps
|
|
433
|
+
|
|
434
|
+
### For Testing:
|
|
435
|
+
1. ✅ **Create more test scenarios** - Try different policy violations
|
|
436
|
+
2. ✅ **Test rate limiting** - Create 11 PRs in a day (should deny 11th)
|
|
437
|
+
3. ✅ **Test expiration** - Set expiration to past date, verify it denies
|
|
438
|
+
|
|
439
|
+
### For Integration:
|
|
440
|
+
1. ✅ **Add to OpenClaw AGENTS.md** - Make it automatic
|
|
441
|
+
2. ✅ **Create custom policy packs** - Add policies for your use case
|
|
442
|
+
3. ✅ **Set up recurring passport renewal** - Cron job to renew every 30 days
|
|
443
|
+
|
|
444
|
+
### For Production:
|
|
445
|
+
1. ✅ **Upgrade to APort Cloud** - Get global kill switch, Ed25519 signatures
|
|
446
|
+
2. ✅ **Set up team passports** - Share policies across team
|
|
447
|
+
3. ✅ **Enable audit log monitoring** - Alert on policy violations
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Resources
|
|
452
|
+
|
|
453
|
+
- [OpenClaw Local Integration](OPENCLAW_LOCAL_INTEGRATION.md) — Full OpenClaw + API setup
|
|
454
|
+
- [QuickStart: OpenClaw Plugin](QUICKSTART_OPENCLAW_PLUGIN.md) — Plugin setup
|
|
455
|
+
- [Tool / Policy Mapping](TOOL_POLICY_MAPPING.md)
|
|
456
|
+
- [Contributing](../CONTRIBUTING.md)
|
|
457
|
+
|
|
458
|
+
---
|
|
459
|
+
|
|
460
|
+
## Get Help
|
|
461
|
+
|
|
462
|
+
- **GitHub Issues:** https://github.com/aporthq/aport-agent-guardrails/issues
|
|
463
|
+
- **Discussions:** https://github.com/aporthq/aport-agent-guardrails/discussions
|
|
464
|
+
- **Email:** uchi@aport.io
|
|
465
|
+
|
|
466
|
+
---
|
|
467
|
+
|
|
468
|
+
**Total Time:** ~5 minutes to get started, 30 minutes to fully integrate
|
|
469
|
+
|
|
470
|
+
**You're now running policy-enforced AI agents! 🎉**
|