@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,114 @@
|
|
|
1
|
+
# APort Agent Guardrail — CrewAI
|
|
2
|
+
|
|
3
|
+
CrewAI supports **tool call hooks** that run before (and after) every tool execution. The **APort Agent Guardrail for CrewAI** plugs into the **before tool call** hook: we verify the tool and parameters against your passport and policy; if the decision is deny, we return `False` and CrewAI blocks execution. This matches CrewAI’s [Tool Call Hooks](https://docs.crewai.com/en/learn/tool-hooks) model.
|
|
4
|
+
|
|
5
|
+
## How CrewAI agent guardrails work
|
|
6
|
+
|
|
7
|
+
- **Hooks:** CrewAI runs **before_tool_call** hooks before every tool execution. The hook receives a `ToolCallHookContext` (tool name, tool input, agent, task, crew). Returning `False` blocks execution; `True` or `None` allows it.
|
|
8
|
+
- **Registration:** You can register a hook **globally** with `register_before_tool_call_hook()`, or use the `@before_tool_call` decorator, or use **crew-scoped** `@before_tool_call_crew` on a `@CrewBase` class.
|
|
9
|
+
- **Multi-task crews:** The same hook runs for every tool call across all tasks and agents, so multi-task crews are supported by default.
|
|
10
|
+
|
|
11
|
+
Our adapter provides a function that fits this API: it calls the APort evaluator (sync) and returns `False` on deny, `None` on allow. You register it once before running your crew.
|
|
12
|
+
|
|
13
|
+
- **Integration:** CrewAI `before_tool_call` hook (global or crew-scoped)
|
|
14
|
+
- **Config:** `~/.aport/crewai/config.yaml` or `.aport/config.yaml` (see [Verification methods](../VERIFICATION_METHODS.md))
|
|
15
|
+
|
|
16
|
+
## Two ways to use APort
|
|
17
|
+
|
|
18
|
+
| Use case | What it is | When to use it |
|
|
19
|
+
|----------|------------|----------------|
|
|
20
|
+
| **Guardrails (CLI/setup)** | One-line installer: runs the **passport wizard**, writes config, prints next steps. Does not run your app. | Getting started: create passport and config so the library can find them. |
|
|
21
|
+
| **Core (library)** | The **evaluator** and **before-tool-call hook** in your code. Calls policy + passport to allow/deny each tool call. | Integrating into your app: register the hook so CrewAI blocks tool runs when policy denies. |
|
|
22
|
+
|
|
23
|
+
You typically use **both**: run the CLI once to create passport and config, then use the library in your CrewAI app so every tool call is verified.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Setup (Guardrails — create passport and config)
|
|
28
|
+
|
|
29
|
+
**Python**
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx @aporthq/aport-agent-guardrails crewai # wizard + config (optional)
|
|
33
|
+
pip install aport-agent-guardrails-crewai
|
|
34
|
+
aport-crewai setup
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
**Node**
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx @aporthq/aport-agent-guardrails crewai # wizard + config
|
|
41
|
+
npm install @aporthq/aport-agent-guardrails-crewai # beforeToolCall, withAPortGuardrail (depends on -core)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
`aport-crewai setup` (Python) writes config to `~/.aport/crewai/`, runs the passport wizard (or use `--ci` / `--no-wizard` for non-interactive), and prints next steps.
|
|
45
|
+
|
|
46
|
+
## Using the library (Core) in your app
|
|
47
|
+
|
|
48
|
+
**Python — Option 1: Register the hook before kickoff**
|
|
49
|
+
|
|
50
|
+
```python
|
|
51
|
+
from aport_guardrails_crewai import register_aport_guardrail
|
|
52
|
+
|
|
53
|
+
register_aport_guardrail()
|
|
54
|
+
crew.kickoff()
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
**Python — Option 2: Decorator on your entry point**
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from aport_guardrails_crewai import with_aport_guardrail
|
|
61
|
+
|
|
62
|
+
@with_aport_guardrail
|
|
63
|
+
def main():
|
|
64
|
+
crew.kickoff()
|
|
65
|
+
|
|
66
|
+
main()
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
**Python — Option 3: Use the hook with `@before_tool_call`**
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from crewai.hooks import before_tool_call
|
|
73
|
+
from aport_guardrails_crewai import aport_guardrail_before_tool_call
|
|
74
|
+
|
|
75
|
+
@before_tool_call
|
|
76
|
+
def my_guardrail(context):
|
|
77
|
+
return aport_guardrail_before_tool_call(context)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Node:** Call `beforeToolCall` in your flow before each tool run (CrewAI Node SDK does not expose a global hook). Return `false` to block, `null` to allow. Or wrap your entry point with `withAPortGuardrail(fn)`.
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
import { beforeToolCall, withAPortGuardrail } from '@aporthq/aport-agent-guardrails-crewai';
|
|
84
|
+
|
|
85
|
+
// In your tool-call flow, before executing a tool:
|
|
86
|
+
const result = beforeToolCall({ tool_name: 'run_command', tool_input: { command: 'ls' } });
|
|
87
|
+
if (result === false) {
|
|
88
|
+
// Block this tool call
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Or wrap your crew kickoff so guardrail is in scope:
|
|
93
|
+
withAPortGuardrail(() => {
|
|
94
|
+
crew.kickoff();
|
|
95
|
+
});
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Config
|
|
99
|
+
|
|
100
|
+
- **Config path:** `~/.aport/crewai/config.yaml`, or `.aport/config.yaml` in the project root.
|
|
101
|
+
- **Mode:** `api` (default for production) or `local` (bash evaluator, no network). Same options as [LangChain](langchain.md) and OpenClaw.
|
|
102
|
+
|
|
103
|
+
## Suspend (kill switch)
|
|
104
|
+
|
|
105
|
+
Same as all frameworks: **passport is the source of truth**. Local: set passport `status` to `suspended` (or `active` to resume). API: suspend the passport in [APort](https://aport.io); all agents using that passport deny within ≤30s.
|
|
106
|
+
|
|
107
|
+
## Example and tests
|
|
108
|
+
|
|
109
|
+
- **Example:** [examples/crewai/run_with_guardrail.py](../../examples/crewai/run_with_guardrail.py) — temp config, ALLOW then DENY, `register_aport_guardrail()`.
|
|
110
|
+
- **Unit tests:** [python/crewai_adapter/tests/test_hook.py](../../python/crewai_adapter/tests/test_hook.py) — hook return value and context with mocked evaluator.
|
|
111
|
+
|
|
112
|
+
## Status
|
|
113
|
+
|
|
114
|
+
Implemented (Story D). **APort Agent Guardrail for CrewAI.** Package: `aport-agent-guardrails-crewai`; CLI: `aport-crewai setup`; hook: `aport_guardrail_before_tool_call` / `register_aport_guardrail` / `with_aport_guardrail`.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# APort Agent Guardrail — Cursor (and VS Code Copilot / Claude Code)
|
|
2
|
+
|
|
3
|
+
Cursor, VS Code with GitHub Copilot, and Claude Code support **config-driven hooks** that run before shell execution or tool use. The **APort hook script** reads JSON from stdin, calls the existing APort guardrail (policy + passport), and returns allow/deny; **exit 2** blocks the action. One script works across Cursor, Copilot, and Claude Code.
|
|
4
|
+
|
|
5
|
+
## Two ways to use APort
|
|
6
|
+
|
|
7
|
+
| Use case | What it is | When to use it |
|
|
8
|
+
|----------|------------|----------------|
|
|
9
|
+
| **Guardrails (CLI/setup)** | One-line installer: runs the **passport wizard**, writes **`~/.cursor/hooks.json`** with the path to the APort hook script. Does not run Cursor for you. | Getting started: create passport and install the hook so Cursor calls our script before the agent runs a command or tool. |
|
|
10
|
+
| **Core (runtime)** | The **hook script** (`bin/aport-cursor-hook.sh`) and **evaluator** (bash or API): when the agent runs a command/tool, Cursor invokes the script; we verify and return allow/deny. Optionally, the **Node package** `@aporthq/aport-agent-guardrails-cursor` exposes `Evaluator` and `getHookPath()` if you need them in code. | Guardrails = after setup, the hook runs automatically. Use the Node package only if you're building tooling that needs the evaluator or hook path. |
|
|
11
|
+
|
|
12
|
+
For Cursor, you almost always use **Guardrails (CLI)** once to install the hook; the **Core** behavior (the script + evaluator) then runs automatically whenever the agent uses the terminal or a tool.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## How it works
|
|
17
|
+
|
|
18
|
+
- **Hooks:** Cursor uses `~/.cursor/hooks.json` (or `.cursor/hooks.json` in the project). Hooks such as `beforeShellExecution` and `preToolUse` run a command (our script). The host sends JSON to stdin and reads JSON from stdout; **exit code 2** = block.
|
|
19
|
+
- **VS Code Copilot:** Agent hooks (Preview) use `~/.claude/settings.json` or `.github/hooks/*.json` with `PreToolUse`; same idea: command, stdin JSON, stdout JSON, exit 2 = block.
|
|
20
|
+
- **Claude Code:** `~/.claude/settings.json`, same PreToolUse style.
|
|
21
|
+
|
|
22
|
+
Our script accepts Cursor- and Copilot-style payloads (e.g. `command`, or `tool`/`input`), maps to the **system.command.execute** policy, calls the bash guardrail, and returns `permission: allow|deny` plus optional `agentMessage`. No VS Code extension is required for interception; hooks are the mechanism.
|
|
23
|
+
|
|
24
|
+
**Hook script path:** The hook script (`aport-cursor-hook.sh`) resolves `bin/aport-guardrail-bash.sh` relative to its own directory (script dir → parent = package root). When you install via **npx**, the installer writes the path to the script inside the npx cache (e.g. `…/node_modules/@aporthq/aport-agent-guardrails/bin/aport-cursor-hook.sh`), so the guardrail script is found at `…/bin/aport-guardrail-bash.sh`. If you copy the hook script elsewhere, ensure `bin/aport-guardrail-bash.sh` exists at the same relative location or set `APORT_GUARDRAIL_SCRIPT` (or equivalent) so the hook can find the evaluator.
|
|
25
|
+
|
|
26
|
+
## Setup
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npx @aporthq/aport-agent-guardrails cursor
|
|
30
|
+
# or
|
|
31
|
+
npx @aporthq/aport-agent-guardrails --framework=cursor
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
This runs the **passport wizard** and writes **`~/.cursor/hooks.json`** with the path to the APort hook script. The wizard uses a **framework-specific default** for where to store the passport: for Cursor the default is **`~/.cursor/aport/passport.json`** (so passport and evaluation data live with Cursor’s own data). The **first question** in the wizard is “Passport file path [default]:” — press Enter to use that default or type a different path. In non-interactive mode you can pass **`--output /path/to/passport.json`** to choose the path. Restart Cursor (or reload the window) after setup so the hooks are loaded.
|
|
35
|
+
|
|
36
|
+
## Is it installed? How to check
|
|
37
|
+
|
|
38
|
+
- **No `~/.cursor/hooks.json`?** That file is **created when you run the installer**. If you get `No such file or directory`, the Cursor integration is not installed yet. Run:
|
|
39
|
+
```bash
|
|
40
|
+
npx @aporthq/aport-agent-guardrails cursor
|
|
41
|
+
```
|
|
42
|
+
(or `npx @aporthq/aport-agent-guardrails --framework=cursor`). The installer writes `~/.cursor/hooks.json` and runs the passport wizard.
|
|
43
|
+
- **Hooks file:** After installing, open `~/.cursor/hooks.json` (user-level) or `.cursor/hooks.json` (project). You should see `beforeShellExecution` and/or `preToolUse` entries whose `command` is the path to `aport-cursor-hook.sh`.
|
|
44
|
+
- **Restart required:** Cursor loads hooks at startup. After installing, **restart Cursor** (or **Reload Window** from the command palette) so the new hooks are active.
|
|
45
|
+
- **Passport:** The hook uses the passport created by the wizard. The default path for Cursor is **`~/.cursor/aport/passport.json`** (each framework has its own default; see [Default paths](#config) below). The resolver probes `~/.cursor`, then `~/.openclaw`, etc., so the hook finds the passport without extra config.
|
|
46
|
+
|
|
47
|
+
## What the guardrail applies to (and what it doesn’t)
|
|
48
|
+
|
|
49
|
+
The guardrail only runs when the **Cursor agent** is about to run a shell command or use a tool. It does **not** run when **you** type commands in the terminal yourself.
|
|
50
|
+
|
|
51
|
+
| Who runs the command | Hook runs? | Guardrail can block? |
|
|
52
|
+
|----------------------|------------|------------------------|
|
|
53
|
+
| **You** type `rm file` in the Cursor terminal | No | No — it’s your shell, not the agent. |
|
|
54
|
+
| **The agent** runs a command (e.g. after you ask “run rm file”) | Yes (`beforeShellExecution`) | Yes — exit 2 blocks the agent’s command. |
|
|
55
|
+
| **The agent** uses a tool that sends a command | Yes (`preToolUse`) | Yes. |
|
|
56
|
+
| **The agent** uses a built-in “delete file” action (no shell) | No | No — direct file API, no hook. |
|
|
57
|
+
|
|
58
|
+
So:
|
|
59
|
+
|
|
60
|
+
- **Checked:** When the **agent** runs a command in the terminal (e.g. `rm file`, `npm install`) or uses a tool that goes through the hook → our script runs and can block (exit 2).
|
|
61
|
+
- **Not checked:** (1) **You** typing in the terminal — the hook is never invoked. (2) The agent using a built-in “delete file” / “edit file” action (editor API) — no shell, so no hook.
|
|
62
|
+
|
|
63
|
+
To **test that the guardrail is working**, ask the **agent** to run a terminal command your passport blocks (e.g. “Run in the terminal: `rm -rf /path/to/file`”). Do **not** type the command yourself in the terminal — that bypasses the hook.
|
|
64
|
+
|
|
65
|
+
## Test the guardrail and inspect status/logs
|
|
66
|
+
|
|
67
|
+
**Two ways to test:** (1) Run the hook from the terminal to verify the script and populate the audit log. (2) Ask the Cursor **agent** to run a command in chat to verify the full installation.
|
|
68
|
+
|
|
69
|
+
### 1. Test the script (terminal)
|
|
70
|
+
|
|
71
|
+
From the repo root (or wherever the hook script lives):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
# Allow path (e.g. cat a file) — exit 0
|
|
75
|
+
echo '{"command":"cat test.md"}' | bin/aport-cursor-hook.sh
|
|
76
|
+
echo "Exit: $?"
|
|
77
|
+
|
|
78
|
+
# Deny path (e.g. rm -rf) — exit 2
|
|
79
|
+
echo '{"command":"rm -rf test.md"}' | bin/aport-cursor-hook.sh
|
|
80
|
+
echo "Exit: $?"
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 2. Inspect status and audit log
|
|
84
|
+
|
|
85
|
+
After running the hook (or after the agent runs a command), check the passport and decisions:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# From repo root: status (passport, capabilities, limits, latest decision, recent activity)
|
|
89
|
+
bin/aport-status.sh
|
|
90
|
+
|
|
91
|
+
# Audit log: one line per decision (timestamp, tool, decision_id, allow/deny, policy, context e.g. command)
|
|
92
|
+
cat ~/.cursor/aport/audit.log
|
|
93
|
+
|
|
94
|
+
# Last decision (full OAP JSON)
|
|
95
|
+
cat ~/.cursor/aport/decision.json
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
If you used a different passport path during setup, the audit log and decision file are in that path’s `aport/` dir (e.g. `~/.openclaw/aport/` if you chose the OpenClaw default).
|
|
99
|
+
|
|
100
|
+
### 3. Test the real installation (Cursor agent)
|
|
101
|
+
|
|
102
|
+
In **Cursor chat**, ask the agent to run a command (do not type it in the terminal yourself):
|
|
103
|
+
|
|
104
|
+
- **Should allow:** “Run in the terminal: `cat test.md`” — command runs; audit log gets an `allow=true` line.
|
|
105
|
+
- **Should block:** “Run in the terminal: `rm -rf test.md`” — Cursor should block the command; audit log gets an `allow=false` line.
|
|
106
|
+
|
|
107
|
+
Then run `bin/aport-status.sh` and `cat ~/.cursor/aport/audit.log` to confirm the new entries.
|
|
108
|
+
|
|
109
|
+
## Config
|
|
110
|
+
|
|
111
|
+
- **Hooks file:** `~/.cursor/hooks.json` (user) or `.cursor/hooks.json` (project). The installer writes the former by default.
|
|
112
|
+
- **Passport and default paths:** Each framework stores passport and evaluation data in its own default location. For Cursor the default is **`~/.cursor/aport/passport.json`** (with `decision.json` and `audit.log` in `~/.cursor/aport/`). You can always choose a different path: in the wizard the first question is the passport path (default shown in brackets); in non-interactive mode use **`--output /path/to/passport.json`**. The Python evaluator and bash resolver use the same default-path map (e.g. `python/aport_guardrails/core/evaluator.py` → `DEFAULT_PASSPORT_PATHS`, `bin/lib/config.sh` → `get_default_passport_path`).
|
|
113
|
+
- **Hook script:** `bin/aport-cursor-hook.sh` in this repo (or in the npm package when installed via npx). The installer puts its absolute path into `hooks.json`. The hook does not set a config dir; the path resolver probes `~/.cursor`, `~/.openclaw`, `~/.aport/langchain`, etc., and uses the first directory that contains `aport/passport.json`.
|
|
114
|
+
|
|
115
|
+
## Status and logs
|
|
116
|
+
|
|
117
|
+
- **Passport status:** Run `bin/aport-status.sh` (from repo) or the guardrail’s status script. It uses the same path resolution as the hook (probes `~/.cursor`, `~/.openclaw`, etc.), so it will show the passport under `~/.cursor/aport/` if that’s where you created it.
|
|
118
|
+
- **Audit trail:** Allow/deny decisions are appended to the audit log in the same data dir as the passport (e.g. `~/.cursor/aport/audit.log` when using the Cursor default). Each line includes timestamp, tool, decision_id, allow/deny, policy id, and **context** (the actual command for `system.command.execute`, recipient for messaging, repo/branch for merge). `bin/aport-status.sh` shows this context in **Latest Decision** and **Recent Activity**.
|
|
119
|
+
|
|
120
|
+
## Suspend (kill switch)
|
|
121
|
+
|
|
122
|
+
Same as all frameworks: **passport is the source of truth**. Set passport `status` to `suspended` (or `active` to resume). The guardrail denies every call until the passport is active again.
|
|
123
|
+
|
|
124
|
+
## Using the same script in VS Code (Copilot) and Claude Code
|
|
125
|
+
|
|
126
|
+
- **VS Code + GitHub Copilot:** Add a PreToolUse hook in `~/.claude/settings.json` (or project `.claude/settings.json`, or `.github/hooks/*.json`) that runs the same script. See [Agent hooks (Preview)](https://code.visualstudio.com/docs/copilot/customization/hooks).
|
|
127
|
+
- **Claude Code:** Configure `~/.claude/settings.json` to run the same APort hook script for PreToolUse.
|
|
128
|
+
|
|
129
|
+
The script accepts multiple input shapes (e.g. `command`, `tool`/`input`) and returns the host-expected JSON; **exit 0** = allow, **exit 2** = block.
|
|
130
|
+
|
|
131
|
+
## Using the Node package (optional)
|
|
132
|
+
|
|
133
|
+
If you need the evaluator or hook path in your own Node/TypeScript code (e.g. custom tooling or scripts):
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm install @aporthq/aport-agent-guardrails-cursor # or -core if you only need Evaluator
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
import { Evaluator, getHookPath } from '@aporthq/aport-agent-guardrails-cursor';
|
|
141
|
+
|
|
142
|
+
// Default path where the hook script is expected (~/.cursor/aport-cursor-hook.sh)
|
|
143
|
+
const hookPath = getHookPath();
|
|
144
|
+
|
|
145
|
+
// Use the evaluator programmatically (same as @aporthq/aport-agent-guardrails-core)
|
|
146
|
+
const evaluator = new Evaluator(null, 'cursor');
|
|
147
|
+
const decision = evaluator.verifySync({}, { capability: 'system.command.execute.v1' }, { tool: 'run_command', input: 'ls' });
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Runtime enforcement in Cursor is done by the **hook script**, not by this package; the package is for programmatic use only.
|
|
151
|
+
|
|
152
|
+
## Tests
|
|
153
|
+
|
|
154
|
+
- **Unit:** Hook script with mock stdin — allow (exit 0, JSON `allowed: true`), deny (exit 2, `allowed: false`). See `tests/unit/test-cursor-hook.sh`.
|
|
155
|
+
- **Integration:** Run script with sample Cursor-style JSON; assert output format and exit code. Cursor setup: `tests/frameworks/cursor/setup.sh` (writes hooks.json, config dir).
|
|
156
|
+
|
|
157
|
+
## Status
|
|
158
|
+
|
|
159
|
+
Implemented (Story E). **APort Agent Guardrail for Cursor.** Installer: `npx @aporthq/aport-agent-guardrails cursor`; hook script: `bin/aport-cursor-hook.sh`; config: `~/.cursor/hooks.json`. Same script usable for VS Code Copilot and Claude Code.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# APort Agent Guardrail — LangChain / LangGraph
|
|
2
|
+
|
|
3
|
+
**How the agent guardrail works:** LangChain’s callback system exposes `on_tool_start` (and related hooks) on `BaseCallbackHandler` / `AsyncCallbackHandler`. The **APort Agent Guardrail for LangChain** implements a callback that runs when a tool is about to execute; we call the APort evaluator and raise to block execution if denied. Note: in some agent setups, tool callbacks can be unreliable; register callbacks on the executor and test your flow.
|
|
4
|
+
|
|
5
|
+
- **Integration:** `AsyncCallbackHandler` with `on_tool_start` (or equivalent)
|
|
6
|
+
- **Config:** `~/.aport/langchain/` or `.aport/config.yaml`
|
|
7
|
+
|
|
8
|
+
## Two ways to use APort
|
|
9
|
+
|
|
10
|
+
| Use case | What it is | When to use it |
|
|
11
|
+
|----------|------------|----------------|
|
|
12
|
+
| **Guardrails (CLI/setup)** | One-line installer: runs the **passport wizard**, writes config, prints next steps. Does not run your app. | Getting started: create passport and config so the library can find them. |
|
|
13
|
+
| **Core (library)** | The **evaluator** and **framework callback** in your code. Calls policy + passport to allow/deny each tool call. | Integrating into your app: add the callback so tool runs are checked before execution. |
|
|
14
|
+
|
|
15
|
+
You typically use **both**: run the CLI once to create passport and config, then use the library in your LangChain app so every tool call is verified.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Setup (Guardrails — create passport and config)
|
|
20
|
+
|
|
21
|
+
**Python**
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @aporthq/aport-agent-guardrails langchain # wizard + config (optional)
|
|
25
|
+
pip install aport-agent-guardrails-langchain
|
|
26
|
+
aport-langchain setup
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Node**
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npx @aporthq/aport-agent-guardrails langchain # wizard + config
|
|
33
|
+
npm install @aporthq/aport-agent-guardrails-langchain # callback handler (depends on -core)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Using the library (Core) in your app
|
|
37
|
+
|
|
38
|
+
**Python:** Add `APortCallback()` to your agent's callbacks. Config is read from `~/.aport/langchain/` or `.aport/config.yaml`.
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
from langchain.agents import initialize_agent
|
|
42
|
+
from aport_guardrails_langchain import APortCallback
|
|
43
|
+
|
|
44
|
+
agent = initialize_agent(
|
|
45
|
+
tools=tools,
|
|
46
|
+
llm=llm,
|
|
47
|
+
callbacks=[APortCallback()]
|
|
48
|
+
)
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
**Node:** Add `APortGuardrailCallback` to your chain/agent callbacks. Config is read from `~/.aport/langchain/` or `.aport/config.yaml`.
|
|
52
|
+
|
|
53
|
+
```ts
|
|
54
|
+
import { APortGuardrailCallback } from '@aporthq/aport-agent-guardrails-langchain';
|
|
55
|
+
|
|
56
|
+
const callback = new APortGuardrailCallback(); // optional: { configPath: '...', framework: 'langchain' }
|
|
57
|
+
// Pass callback to your LangChain run (e.g. callbacks: [callback])
|
|
58
|
+
// On deny, the callback throws GuardrailViolationError.
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Config
|
|
62
|
+
|
|
63
|
+
- **Config:** `~/.aport/langchain/` or `.aport/config.yaml`
|
|
64
|
+
- **Usage:** Add the callback to your agent (see above).
|
|
65
|
+
|
|
66
|
+
## Suspend (kill switch)
|
|
67
|
+
|
|
68
|
+
Same standard as all frameworks: **passport is the source of truth**—no separate file. Local: set passport `status` to `suspended` (or `active` to resume). Remote: use API mode and suspend in [APort](https://aport.io); all agents using that passport deny within ≤30s.
|
|
69
|
+
|
|
70
|
+
## Status
|
|
71
|
+
|
|
72
|
+
Implemented. **APort Agent Guardrail for LangChain.** Package: `aport-agent-guardrails-langchain`; CLI: `aport-langchain setup`.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# APort Guardrails — n8n
|
|
2
|
+
|
|
3
|
+
**Coming soon.** n8n support is not yet available; custom node and runtime integration are in progress.
|
|
4
|
+
|
|
5
|
+
**How guardrails work (planned):** n8n workflows run as a graph of nodes. We provide a custom **APort Guardrail** node that calls the evaluator (API or local); the node outputs allow/deny. You place it **before** action nodes and branch on the result (e.g. IF node on allow) so that only allowed actions run. No code; guardrail is enforced by workflow structure.
|
|
6
|
+
|
|
7
|
+
- **Integration:** Custom node (or HTTP Request node to APort API) before action nodes; branch on allow/deny
|
|
8
|
+
- **Config:** n8n credentials store (agent_id or passport)
|
|
9
|
+
|
|
10
|
+
## Two ways to use APort (planned)
|
|
11
|
+
|
|
12
|
+
| Use case | What it is | When to use it |
|
|
13
|
+
|----------|------------|----------------|
|
|
14
|
+
| **Guardrails (CLI/setup)** | Installer: runs the **passport wizard**, writes config; (when shipped) installs the **custom node** so workflows can use the APort Guardrail node. | Getting started: create passport and config; install the node so it appears in n8n. |
|
|
15
|
+
| **Core (library / node)** | The **evaluator** and **custom node**: your workflow calls the node before an action; the node returns allow/deny so you can branch. The npm package `@aporthq/aport-agent-guardrails-n8n` is not published yet. | When available: add the APort Guardrail node before action nodes and branch on the result. |
|
|
16
|
+
|
|
17
|
+
n8n support is **coming soon**; the custom node and npm package are not yet released.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Setup
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @aporthq/aport-agent-guardrails n8n
|
|
25
|
+
# Runs passport wizard and writes config only. Custom node is NOT yet available.
|
|
26
|
+
# When the node is released, it will install to ~/.n8n/custom/ and you will restart n8n.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Config
|
|
30
|
+
|
|
31
|
+
- **Credentials:** n8n credentials store (agent_id or passport)
|
|
32
|
+
- **Workflow:** Drag "APort Guardrail" node before action; branch on allow/deny.
|
|
33
|
+
|
|
34
|
+
## Suspend (kill switch)
|
|
35
|
+
|
|
36
|
+
Same standard as all frameworks: **passport is the source of truth**—no separate file. Local: set passport `status` to `suspended` (or `active` to resume). Remote: use API mode and suspend in [APort](https://aport.io); all agents using that passport deny within ≤30s.
|
|
37
|
+
|
|
38
|
+
## Status
|
|
39
|
+
|
|
40
|
+
High priority (Phase 3).
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# APort Guardrails — OpenClaw
|
|
2
|
+
|
|
3
|
+
**How guardrails work:** OpenClaw’s plugin API provides a `before_tool_call` hook that runs **before every tool execution**. The APort plugin registers this hook and calls the shared evaluator (API or local script); the platform blocks the tool if the evaluator returns deny. The model cannot skip it.
|
|
4
|
+
|
|
5
|
+
- **Integration:** `before_tool_call` plugin (`extensions/openclaw-aport`)
|
|
6
|
+
- **Config:** `~/.openclaw/aport-config.yaml`
|
|
7
|
+
|
|
8
|
+
## Two ways to use APort
|
|
9
|
+
|
|
10
|
+
| Use case | What it is | When to use it |
|
|
11
|
+
|----------|------------|----------------|
|
|
12
|
+
| **Guardrails (CLI/setup)** | Full installer: runs the **passport wizard**, writes config, installs the **OpenClaw plugin** so every tool call goes through the evaluator. | Getting started: one command sets up config, passport, and the plugin. |
|
|
13
|
+
| **Core (runtime)** | The **evaluator** (bash script or API) that the plugin calls before each tool run. Same policy + passport as other frameworks. For **programmatic** use (e.g. custom scripts), you can use the **Python** (`aport_guardrails`) or **Node** (`@aporthq/aport-agent-guardrails-core`) library. | Guardrails = the plugin uses the evaluator automatically. Use the library only if you're building custom tooling. |
|
|
14
|
+
|
|
15
|
+
For OpenClaw, you use **Guardrails (CLI)** once to install the plugin; the **Core** (evaluator) then runs automatically on every tool call.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Setup
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx @aporthq/aport-agent-guardrails openclaw
|
|
23
|
+
# or
|
|
24
|
+
npx @aporthq/aport-agent-guardrails
|
|
25
|
+
# then choose openclaw
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Config
|
|
29
|
+
|
|
30
|
+
- **Config dir:** `~/.openclaw` (or `OPENCLAW_HOME`)
|
|
31
|
+
- **Passport:** Created by wizard or use hosted `agent_id`
|
|
32
|
+
- **Plugin:** `extensions/openclaw-aport`
|
|
33
|
+
|
|
34
|
+
## Suspend (kill switch)
|
|
35
|
+
|
|
36
|
+
Same standard as all frameworks: **passport is the source of truth**—no separate file. Local: set passport `status` to `suspended` (or `active` to resume). Remote: use API mode and suspend in [APort](https://aport.io); all agents using that passport deny within ≤30s.
|
|
37
|
+
|
|
38
|
+
## Status
|
|
39
|
+
|
|
40
|
+
Shipped; in production.
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
# Add APort Agent Guardrails to Awesome Lists — Instructions
|
|
2
|
+
|
|
3
|
+
Standard open-source workflow: **fork upstream → clone your fork → edit → push → open PR from your fork to upstream.**
|
|
4
|
+
|
|
5
|
+
Use the script `docs/launch/scripts/add-aport-awesome-pr.sh`. Repo details from [README.md](../../README.md) and [package.json](../../package.json).
|
|
6
|
+
|
|
7
|
+
**Standard entry (short):**
|
|
8
|
+
- **Name:** APort Agent Guardrails
|
|
9
|
+
- **Repo:** https://github.com/aporthq/aport-agent-guardrails
|
|
10
|
+
- **npm:** https://www.npmjs.com/package/@aporthq/aport-agent-guardrails
|
|
11
|
+
- **Description:** Pre-action authorization for OpenClaw/agent frameworks. `before_tool_call` plugin, 40+ blocked patterns, local or API.
|
|
12
|
+
- **Setup:** `npx @aporthq/aport-agent-guardrails`
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 1. SamurAIGPT/awesome-openclaw
|
|
17
|
+
|
|
18
|
+
- **Fork + clone:** Run the script (see workflow below). Your fork is cloned to `/tmp/aport-awesome-prs/SamurAIGPT-awesome-openclaw/`; `origin` = your fork.
|
|
19
|
+
- **File:** `README.md`
|
|
20
|
+
- **Section:** `## Security` → **Security Tools** table (after the aquaman row).
|
|
21
|
+
- **Add this row** (after the line with `aquaman`):
|
|
22
|
+
|
|
23
|
+
```markdown
|
|
24
|
+
| [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) | - | Pre-action authorization for OpenClaw; `before_tool_call` plugin, allowlist + 40+ blocked patterns, local or API. Setup: `npx @aporthq/aport-agent-guardrails` |
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- **Anchor:** Search for `### Security Tools` then the table with `| [aquaman]`. Add the new row after the aquaman row (before `### Security Resources`).
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## 2. VoltAgent/awesome-openclaw-skills
|
|
32
|
+
|
|
33
|
+
- **Fork + clone:** Run the script. Your fork is cloned to `/tmp/aport-awesome-prs/VoltAgent-awesome-openclaw-skills/`; `origin` = your fork.
|
|
34
|
+
- **File:** `README.md`
|
|
35
|
+
- **Section:** **### Security & Passwords** — add in alphabetical order with other skills (same bullet format as existing entries).
|
|
36
|
+
- **Add** (match list format: `- [slug](url) - description`; alphabetically after amai-id, before audit-badge-demo):
|
|
37
|
+
|
|
38
|
+
```markdown
|
|
39
|
+
- [aport-agent-guardrails](https://github.com/aporthq/aport-agent-guardrails) - Pre-action authorization for OpenClaw; before_tool_call plugin, 40+ blocked patterns, local or API. Setup: npx @aporthq/aport-agent-guardrails
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
- **Note:** This list only includes skills published in the OpenClaw skills repo; if APort is not there yet, the maintainers may ask you to publish the skill first. See CONTRIBUTING.md.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 3. hesamsheikh/awesome-openclaw-usecases
|
|
47
|
+
|
|
48
|
+
- **Fork + clone:** Script clones your fork to `/tmp/aport-awesome-prs/hesamsheikh-awesome-openclaw-usecases/`.
|
|
49
|
+
- **File:** `README.md`
|
|
50
|
+
- **Section:** Add a new section **## Security & Guardrails** (e.g. after `## Finance & Trading`, before `## 🤝 Contributing`).
|
|
51
|
+
- **Add:**
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
## Security & Guardrails
|
|
55
|
+
|
|
56
|
+
| Name | Description |
|
|
57
|
+
|------|-------------|
|
|
58
|
+
| [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) | Pre-action authorization for OpenClaw; every tool call checked before it runs. Allowlist + 40+ blocked patterns, local or API. Setup: `npx @aporthq/aport-agent-guardrails` |
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 4. Jenqyang/Awesome-AI-Agents
|
|
64
|
+
|
|
65
|
+
- **Fork + clone:** Script clones your fork to `/tmp/aport-awesome-prs/Jenqyang-Awesome-AI-Agents/`.
|
|
66
|
+
- **File:** `README.md`
|
|
67
|
+
- **Section:** Find **Tools** or **Safety / Guardrails** (or similar). If there is a bullet list of tools, add:
|
|
68
|
+
- **Add:**
|
|
69
|
+
|
|
70
|
+
```markdown
|
|
71
|
+
- [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) - Pre-action authorization for OpenClaw and agent frameworks. `before_tool_call` plugin, 40+ blocked patterns, local or API. Setup: `npx @aporthq/aport-agent-guardrails`
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
- **Note:** Open the README and place the entry in the most appropriate subsection (e.g. Tools or a guardrails/safety section). Match existing list style (dash vs table).
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 5. e2b-dev/awesome-ai-agents
|
|
79
|
+
|
|
80
|
+
- **Fork + clone:** Script clones your fork to `/tmp/aport-awesome-prs/e2b-dev-awesome-ai-agents/`.
|
|
81
|
+
- **File:** `README.md`
|
|
82
|
+
- **Section:** Locate a Security / Guardrails / Tools section. Format may be minimal; match existing style.
|
|
83
|
+
- **Add (bullet style):**
|
|
84
|
+
|
|
85
|
+
```markdown
|
|
86
|
+
- [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) - Pre-action authorization for OpenClaw and agent frameworks. `before_tool_call` plugin, 40+ blocked patterns. Setup: `npx @aporthq/aport-agent-guardrails`
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
## 6. slavakurilyak/awesome-ai-agents
|
|
92
|
+
|
|
93
|
+
- **Fork + clone:** Script clones your fork to `/tmp/aport-awesome-prs/slavakurilyak-awesome-ai-agents/`.
|
|
94
|
+
- **File:** `README.md` (or the main list file; check repo structure).
|
|
95
|
+
- **Section:** Find Guardrails / Safety / Security or Tools. Match existing entry format (often project name + stars + description).
|
|
96
|
+
- **Add (adjust to match list style):**
|
|
97
|
+
|
|
98
|
+
```markdown
|
|
99
|
+
- [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) - Pre-action authorization for OpenClaw/agent frameworks; `before_tool_call` plugin, 40+ blocked patterns, local or API. Setup: `npx @aporthq/aport-agent-guardrails`
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## 7. TalEliyahu/Awesome-AI-Security
|
|
105
|
+
|
|
106
|
+
- **Fork + clone:** Script clones your fork to `/tmp/aport-awesome-prs/TalEliyahu-Awesome-AI-Security/`.
|
|
107
|
+
- **File:** `README.md`
|
|
108
|
+
- **Section:** **Jailbreak & Policy Enforcement (Guardrails)** — add after the Guardrails entry (e.g. after the line with `guardrails-ai/guardrails`).
|
|
109
|
+
- **Add** (match their format with GitHub stars badge if they use it):
|
|
110
|
+
|
|
111
|
+
```markdown
|
|
112
|
+
- **[APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails)** [](https://github.com/aporthq/aport-agent-guardrails) - Pre-action authorization for OpenClaw/agent frameworks; `before_tool_call` hook, passport-driven, 40+ blocked patterns, local or API. Setup: `npx @aporthq/aport-agent-guardrails`
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## Repetitive workflow (per repo)
|
|
118
|
+
|
|
119
|
+
1. **Fork and clone** (from this repo root). This forks the upstream repo to your GitHub account and clones your fork:
|
|
120
|
+
```bash
|
|
121
|
+
./docs/launch/scripts/add-aport-awesome-pr.sh <owner/repo>
|
|
122
|
+
```
|
|
123
|
+
Example: `./docs/launch/scripts/add-aport-awesome-pr.sh SamurAIGPT/awesome-openclaw`
|
|
124
|
+
Clone path: `/tmp/aport-awesome-prs/<owner>-<repo>/` (e.g. `SamurAIGPT-awesome-openclaw`). Remote `origin` is your fork.
|
|
125
|
+
|
|
126
|
+
2. **Edit** the clone: open the file and section above, add the exact line(s) for that repo.
|
|
127
|
+
|
|
128
|
+
3. **Push and open PR** (from your fork to upstream):
|
|
129
|
+
```bash
|
|
130
|
+
./docs/launch/scripts/add-aport-awesome-pr.sh <owner/repo> pr
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**PR title (suggested):** `Add APort Agent Guardrails`
|
|
134
|
+
**PR body (suggested):**
|
|
135
|
+
```markdown
|
|
136
|
+
Adds [APort Agent Guardrails](https://github.com/aporthq/aport-agent-guardrails) — pre-action authorization for OpenClaw and compatible agent frameworks. Policy runs in the platform `before_tool_call` hook; 40+ blocked patterns, allowlist, local or API. Setup: `npx @aporthq/aport-agent-guardrails`.
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## Reference
|
|
142
|
+
|
|
143
|
+
- **Repo:** https://github.com/aporthq/aport-agent-guardrails
|
|
144
|
+
- **npm:** https://www.npmjs.com/package/@aporthq/aport-agent-guardrails
|
|
145
|
+
- **Quick start:** https://github.com/aporthq/aport-agent-guardrails/blob/main/docs/QUICKSTART_OPENCLAW_PLUGIN.md
|
|
146
|
+
- **package.json** name: `@aporthq/aport-agent-guardrails`, description: "Policy enforcement guardrails for OpenClaw-compatible agent frameworks"
|