@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,276 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# aport-status.sh
|
|
3
|
+
# Display APort passport status and recent activity
|
|
4
|
+
#
|
|
5
|
+
# Usage: ./aport-status.sh [--passport FILE]
|
|
6
|
+
|
|
7
|
+
set -e
|
|
8
|
+
|
|
9
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
10
|
+
# shellcheck source=bin/aport-resolve-paths.sh
|
|
11
|
+
. "${SCRIPT_DIR}/bin/aport-resolve-paths.sh"
|
|
12
|
+
|
|
13
|
+
if [ "$1" = "--passport" ] && [ -n "$2" ]; then
|
|
14
|
+
PASSPORT_FILE="$2"
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
echo "🛂 APort Status Dashboard"
|
|
18
|
+
echo "========================="
|
|
19
|
+
echo
|
|
20
|
+
|
|
21
|
+
# Passport info (passport status is source of truth for suspend; no separate kill-switch file)
|
|
22
|
+
if [ ! -f "$PASSPORT_FILE" ]; then
|
|
23
|
+
echo "❌ Passport: NOT FOUND"
|
|
24
|
+
echo " Location: $PASSPORT_FILE"
|
|
25
|
+
echo " Create one with: aport-create-passport.sh"
|
|
26
|
+
echo
|
|
27
|
+
exit 1
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
echo "📋 Passport Information"
|
|
31
|
+
echo " Location: $PASSPORT_FILE"
|
|
32
|
+
|
|
33
|
+
# Check jq availability
|
|
34
|
+
if ! command -v jq &> /dev/null; then
|
|
35
|
+
echo " ⚠️ jq not found - install with: brew install jq"
|
|
36
|
+
echo
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
|
|
40
|
+
echo " ID: $(jq -r '.passport_id // "unknown"' $PASSPORT_FILE)"
|
|
41
|
+
echo " Kind: $(jq -r '.kind // "unknown"' $PASSPORT_FILE)"
|
|
42
|
+
echo " Owner: $(jq -r '.owner_id // "unknown"' $PASSPORT_FILE) ($(jq -r '.owner_type // "unknown"' $PASSPORT_FILE))"
|
|
43
|
+
echo " Spec Version: $(jq -r '.spec_version // "unknown"' $PASSPORT_FILE)"
|
|
44
|
+
echo " Assurance Level: $(jq -r '.assurance_level // "unknown"' $PASSPORT_FILE)"
|
|
45
|
+
|
|
46
|
+
# Status with color
|
|
47
|
+
status=$(jq -r '.status // "unknown"' $PASSPORT_FILE)
|
|
48
|
+
if [ "$status" = "active" ]; then
|
|
49
|
+
echo " Status: ✅ active"
|
|
50
|
+
elif [ "$status" = "suspended" ]; then
|
|
51
|
+
echo " Status: 🔴 suspended"
|
|
52
|
+
elif [ "$status" = "revoked" ]; then
|
|
53
|
+
echo " Status: ❌ revoked"
|
|
54
|
+
else
|
|
55
|
+
echo " Status: ⚠️ $status"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Display agent metadata if available
|
|
59
|
+
agent_name=$(jq -r '.metadata.name // ""' $PASSPORT_FILE)
|
|
60
|
+
if [ -n "$agent_name" ] && [ "$agent_name" != "null" ]; then
|
|
61
|
+
echo " Agent Name: $agent_name"
|
|
62
|
+
fi
|
|
63
|
+
|
|
64
|
+
# Expiration with warning
|
|
65
|
+
never_expires=$(jq -r '.never_expires // "false"' $PASSPORT_FILE)
|
|
66
|
+
expires_at=$(jq -r '.expires_at // "null"' $PASSPORT_FILE)
|
|
67
|
+
|
|
68
|
+
if [ "$never_expires" = "true" ]; then
|
|
69
|
+
echo " Expires: Never"
|
|
70
|
+
elif [ "$expires_at" != "null" ] && [ "$expires_at" != "unknown" ]; then
|
|
71
|
+
echo " Expires: $expires_at"
|
|
72
|
+
|
|
73
|
+
# Calculate days until expiration
|
|
74
|
+
if date -v+1d &> /dev/null 2>&1; then
|
|
75
|
+
# BSD date (macOS)
|
|
76
|
+
expires_ts=$(date -jf "%Y-%m-%dT%H:%M:%SZ" "$expires_at" +%s 2> /dev/null || echo 0)
|
|
77
|
+
else
|
|
78
|
+
# GNU date (Linux)
|
|
79
|
+
expires_ts=$(date -d "$expires_at" +%s 2> /dev/null || echo 0)
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
now_ts=$(date +%s)
|
|
83
|
+
days_left=$((($expires_ts - $now_ts) / 86400))
|
|
84
|
+
|
|
85
|
+
if [ $days_left -le 0 ]; then
|
|
86
|
+
echo " ⚠️ EXPIRED $((days_left * -1)) days ago"
|
|
87
|
+
elif [ $days_left -le 7 ]; then
|
|
88
|
+
echo " ⚠️ Expires in $days_left days - renew soon!"
|
|
89
|
+
else
|
|
90
|
+
echo " ✅ $days_left days until expiration"
|
|
91
|
+
fi
|
|
92
|
+
else
|
|
93
|
+
echo " Expires: Not set"
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
echo
|
|
97
|
+
|
|
98
|
+
# Capabilities
|
|
99
|
+
echo "🔐 Capabilities"
|
|
100
|
+
cap_count=$(jq '.capabilities | length' $PASSPORT_FILE)
|
|
101
|
+
if [ "$cap_count" -eq 0 ]; then
|
|
102
|
+
echo " (none configured)"
|
|
103
|
+
else
|
|
104
|
+
jq -r '.capabilities[].id // empty' $PASSPORT_FILE | while read cap; do
|
|
105
|
+
echo " • $cap"
|
|
106
|
+
done
|
|
107
|
+
fi
|
|
108
|
+
|
|
109
|
+
echo
|
|
110
|
+
|
|
111
|
+
# Limits summary
|
|
112
|
+
echo "⚙️ Limits"
|
|
113
|
+
jq -r '.limits | keys[]? // empty' $PASSPORT_FILE | while read policy; do
|
|
114
|
+
echo " • $policy:"
|
|
115
|
+
case "$policy" in
|
|
116
|
+
"code.repository.merge")
|
|
117
|
+
max_prs=$(jq -r ".limits.\"$policy\".max_prs_per_day // \"unlimited\"" $PASSPORT_FILE)
|
|
118
|
+
max_size=$(jq -r ".limits.\"$policy\".max_pr_size_kb // \"unlimited\"" $PASSPORT_FILE)
|
|
119
|
+
echo " - Max PRs/day: $max_prs"
|
|
120
|
+
echo " - Max PR size: $max_size files"
|
|
121
|
+
;;
|
|
122
|
+
"system.command.execute")
|
|
123
|
+
max_time=$(jq -r ".limits.\"$policy\".max_execution_time // \"unlimited\"" $PASSPORT_FILE)
|
|
124
|
+
echo " - Max execution time: $max_time seconds"
|
|
125
|
+
blocked_count=$(jq ".limits.\"$policy\".blocked_patterns | length" $PASSPORT_FILE)
|
|
126
|
+
echo " - Blocked patterns: $blocked_count"
|
|
127
|
+
;;
|
|
128
|
+
"messaging.message.send")
|
|
129
|
+
msgs_per_day=$(jq -r ".limits.\"$policy\".msgs_per_day // \"unlimited\"" $PASSPORT_FILE)
|
|
130
|
+
echo " - Messages/day: $msgs_per_day"
|
|
131
|
+
;;
|
|
132
|
+
"data.export")
|
|
133
|
+
max_rows=$(jq -r ".limits.\"$policy\".max_rows // \"unlimited\"" $PASSPORT_FILE)
|
|
134
|
+
allow_pii=$(jq -r ".limits.\"$policy\".allow_pii // false" $PASSPORT_FILE)
|
|
135
|
+
echo " - Max rows: $max_rows"
|
|
136
|
+
echo " - PII export: $allow_pii"
|
|
137
|
+
;;
|
|
138
|
+
esac
|
|
139
|
+
done
|
|
140
|
+
|
|
141
|
+
echo
|
|
142
|
+
|
|
143
|
+
# Latest decision (OAP v1.0 format)
|
|
144
|
+
if [ -f "$DECISION_FILE" ]; then
|
|
145
|
+
echo "🔍 Latest Decision"
|
|
146
|
+
allow=$(jq -r '.allow // "unknown"' $DECISION_FILE)
|
|
147
|
+
decision_id=$(jq -r '.decision_id // "unknown"' $DECISION_FILE)
|
|
148
|
+
policy_id=$(jq -r '.policy_id // "unknown"' $DECISION_FILE)
|
|
149
|
+
|
|
150
|
+
if [ "$allow" = "true" ]; then
|
|
151
|
+
echo " ✅ ALLOW"
|
|
152
|
+
else
|
|
153
|
+
echo " ❌ DENY"
|
|
154
|
+
fi
|
|
155
|
+
echo " Decision ID: $decision_id"
|
|
156
|
+
echo " Policy ID: $policy_id"
|
|
157
|
+
|
|
158
|
+
# Display OAP v1.0 reasons array
|
|
159
|
+
reasons_count=$(jq '.reasons | length' $DECISION_FILE 2> /dev/null || echo 0)
|
|
160
|
+
if [ "$reasons_count" -gt 0 ]; then
|
|
161
|
+
echo " Reasons:"
|
|
162
|
+
jq -r '.reasons[] | " - [\(.code)] \(.message)"' $DECISION_FILE
|
|
163
|
+
fi
|
|
164
|
+
|
|
165
|
+
# Display issued_at and expires_at
|
|
166
|
+
issued_at=$(jq -r '.issued_at // "unknown"' $DECISION_FILE)
|
|
167
|
+
expires_at_decision=$(jq -r '.expires_at // "unknown"' $DECISION_FILE)
|
|
168
|
+
if [ "$issued_at" != "unknown" ]; then
|
|
169
|
+
echo " Issued: $issued_at"
|
|
170
|
+
fi
|
|
171
|
+
if [ "$expires_at_decision" != "unknown" ]; then
|
|
172
|
+
echo " Expires: $expires_at_decision"
|
|
173
|
+
fi
|
|
174
|
+
|
|
175
|
+
# Display signature info
|
|
176
|
+
kid=$(jq -r '.kid // "unknown"' $DECISION_FILE)
|
|
177
|
+
if [ "$kid" != "unknown" ]; then
|
|
178
|
+
echo " Key ID: $kid"
|
|
179
|
+
fi
|
|
180
|
+
# Show capability context from last audit line (command, recipient, repo/branch)
|
|
181
|
+
if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
|
|
182
|
+
last_context=$(tail -1 "$AUDIT_LOG" | sed -n 's/.*context="\([^"]*\)".*/\1/p')
|
|
183
|
+
if [ -n "$last_context" ]; then
|
|
184
|
+
echo " Context: $last_context"
|
|
185
|
+
fi
|
|
186
|
+
fi
|
|
187
|
+
echo
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# Recent activity
|
|
191
|
+
echo "📊 Recent Activity (last 10)"
|
|
192
|
+
if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
|
|
193
|
+
tail -10 "$AUDIT_LOG" | while IFS= read -r line; do
|
|
194
|
+
# Parse log line: [timestamp] tool=X decision_id=Y allow=Z ... context="..." (optional)
|
|
195
|
+
timestamp=$(echo "$line" | sed -n 's/.*\[\([^]]*\)\].*/\1/p')
|
|
196
|
+
tool=$(echo "$line" | sed -n 's/.*tool=\([^ ]*\).*/\1/p')
|
|
197
|
+
allow=$(echo "$line" | sed -n 's/.*allow=\([^ ]*\).*/\1/p')
|
|
198
|
+
context=$(echo "$line" | sed -n 's/.*context="\([^"]*\)".*/\1/p')
|
|
199
|
+
timestamp=${timestamp:-unknown}
|
|
200
|
+
tool=${tool:-unknown}
|
|
201
|
+
allow=${allow:-unknown}
|
|
202
|
+
|
|
203
|
+
short_time=$(echo "$timestamp" | cut -d' ' -f1-2 | cut -d'.' -f1)
|
|
204
|
+
# Show capability + context when present (e.g. "exec.run | cat test.md"); truncate long context
|
|
205
|
+
if [ -n "$context" ]; then
|
|
206
|
+
context_show=$(printf '%.80s' "$context")
|
|
207
|
+
[ "${#context}" -gt 80 ] && context_show="${context_show}..."
|
|
208
|
+
detail="$tool | $context_show"
|
|
209
|
+
else
|
|
210
|
+
detail="$tool"
|
|
211
|
+
fi
|
|
212
|
+
|
|
213
|
+
if [ "$allow" = "true" ]; then
|
|
214
|
+
printf " ✅ %s | %s\n" "$short_time" "$detail"
|
|
215
|
+
else
|
|
216
|
+
printf " ❌ %s | %s\n" "$short_time" "$detail"
|
|
217
|
+
fi
|
|
218
|
+
done
|
|
219
|
+
else
|
|
220
|
+
echo " (no activity yet)"
|
|
221
|
+
fi
|
|
222
|
+
|
|
223
|
+
echo
|
|
224
|
+
|
|
225
|
+
# Usage statistics (sanitize numbers for macOS/BSD)
|
|
226
|
+
if [ -f "$AUDIT_LOG" ] && [ -s "$AUDIT_LOG" ]; then
|
|
227
|
+
echo "📈 Statistics (all time)"
|
|
228
|
+
total_actions=$(wc -l < "$AUDIT_LOG" | tr -d '[:space:]')
|
|
229
|
+
total_actions=${total_actions:-0}
|
|
230
|
+
allowed=$(grep -c "allow=true" "$AUDIT_LOG" 2> /dev/null || true)
|
|
231
|
+
allowed=$(echo "$allowed" | tr -d '[:space:]')
|
|
232
|
+
allowed=${allowed:-0}
|
|
233
|
+
denied=$(grep -c "allow=false" "$AUDIT_LOG" 2> /dev/null || true)
|
|
234
|
+
denied=$(echo "$denied" | tr -d '[:space:]')
|
|
235
|
+
denied=${denied:-0}
|
|
236
|
+
|
|
237
|
+
echo " Total actions: $total_actions"
|
|
238
|
+
echo " Allowed: $allowed"
|
|
239
|
+
echo " Denied: $denied"
|
|
240
|
+
|
|
241
|
+
if [ -n "$total_actions" ] && [ "$total_actions" -gt 0 ] 2> /dev/null; then
|
|
242
|
+
allow_pct=$((100 * allowed / total_actions))
|
|
243
|
+
echo " Allow rate: ${allow_pct}%"
|
|
244
|
+
fi
|
|
245
|
+
echo
|
|
246
|
+
fi
|
|
247
|
+
|
|
248
|
+
# Commands
|
|
249
|
+
echo "💡 Useful Commands"
|
|
250
|
+
echo " • View full audit log: tail -f $AUDIT_LOG"
|
|
251
|
+
echo " • Edit passport: vim $PASSPORT_FILE"
|
|
252
|
+
echo " • Test policy: aport-guardrail.sh <tool_name> '<context_json>'"
|
|
253
|
+
echo " • Suspend agent (local): set passport status to \"suspended\" in $PASSPORT_FILE (edit with jq or editor)"
|
|
254
|
+
echo " • Resume: set status back to \"active\""
|
|
255
|
+
echo
|
|
256
|
+
|
|
257
|
+
# Upgrade hint (show once per day)
|
|
258
|
+
HINT_FILE="$HOME/.openclaw/.last-status-upgrade-hint"
|
|
259
|
+
if [ ! -f "$HINT_FILE" ] || [ $(($(date +%s) - $(stat -f %m "$HINT_FILE" 2> /dev/null || stat -c %Y "$HINT_FILE" 2> /dev/null || echo 0))) -gt 86400 ]; then
|
|
260
|
+
echo "💰 Upgrade to APort Cloud?"
|
|
261
|
+
echo " You're using APort Local (free tier) - perfect for individual developers!"
|
|
262
|
+
echo
|
|
263
|
+
echo " Upgrade to APort Cloud for teams:"
|
|
264
|
+
echo " • Multi-machine sync (passport changes propagate <15s)"
|
|
265
|
+
echo " • Global suspend (remote passports): log in at aport.io and suspend passport; all agents using it deny in <30s"
|
|
266
|
+
echo " • Ed25519 signed audit logs (court-admissible, SOC 2/IIROC compliant)"
|
|
267
|
+
echo " • Team collaboration (shared passports, role-based policies)"
|
|
268
|
+
echo " • Analytics dashboard (usage metrics, risk scoring, anomaly detection)"
|
|
269
|
+
echo
|
|
270
|
+
echo " Pricing: \$99/user/month (Pro) | \$149/user/month (Enterprise)"
|
|
271
|
+
echo " Free trial: https://aport.io/trial"
|
|
272
|
+
echo " Learn more: https://aport.io/upgrade"
|
|
273
|
+
echo
|
|
274
|
+
|
|
275
|
+
touch "$HINT_FILE"
|
|
276
|
+
fi
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# CrewAI framework installer/setup
|
|
3
|
+
# Config: ~/.aport/crewai/ or .aport/config.yaml
|
|
4
|
+
|
|
5
|
+
LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
|
|
6
|
+
# shellcheck source=../lib/common.sh
|
|
7
|
+
source "$LIB/common.sh"
|
|
8
|
+
# shellcheck source=../lib/passport.sh
|
|
9
|
+
source "$LIB/passport.sh"
|
|
10
|
+
# shellcheck source=../lib/config.sh
|
|
11
|
+
source "$LIB/config.sh"
|
|
12
|
+
|
|
13
|
+
run_setup() {
|
|
14
|
+
log_info "Setting up APort guardrails for CrewAI..."
|
|
15
|
+
config_dir="$(write_config_template crewai)"
|
|
16
|
+
mkdir -p "$config_dir/aport"
|
|
17
|
+
export APORT_FRAMEWORK=crewai
|
|
18
|
+
run_passport_wizard "$@"
|
|
19
|
+
echo ""
|
|
20
|
+
echo " Next steps (CrewAI):"
|
|
21
|
+
echo " ───────────────────"
|
|
22
|
+
echo " 1. Install the Python adapter (required for runtime enforcement):"
|
|
23
|
+
echo " pip install aport-agent-guardrails-crewai"
|
|
24
|
+
echo " aport-crewai setup"
|
|
25
|
+
echo " 2. Config written to: $config_dir"
|
|
26
|
+
echo " 3. Register the guardrail before running your crew:"
|
|
27
|
+
echo ""
|
|
28
|
+
echo " from aport_guardrails_crewai import register_aport_guardrail"
|
|
29
|
+
echo " register_aport_guardrail()"
|
|
30
|
+
echo " crew.kickoff()"
|
|
31
|
+
echo ""
|
|
32
|
+
echo " Or: @with_aport_guardrail on your entry point. See: docs/frameworks/crewai.md"
|
|
33
|
+
echo ""
|
|
34
|
+
# Fail loudly if Python available but adapter not installed (Issue 4); skip in CI/tests
|
|
35
|
+
if [[ -z "${APORT_SKIP_ADAPTER_CHECK:-}" ]]; then
|
|
36
|
+
if command -v pip &> /dev/null || command -v pip3 &> /dev/null; then
|
|
37
|
+
pip_cmd="pip"
|
|
38
|
+
command -v pip3 &> /dev/null && pip_cmd="pip3"
|
|
39
|
+
if ! $pip_cmd show aport-agent-guardrails-crewai &> /dev/null; then
|
|
40
|
+
echo "[aport] ERROR: Python adapter not installed. Run the following, then use your agent:" >&2
|
|
41
|
+
echo " $pip_cmd install aport-agent-guardrails-crewai" >&2
|
|
42
|
+
echo " aport-crewai setup" >&2
|
|
43
|
+
exit 1
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
fi
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
run_setup "$@"
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Cursor (and optional Copilot/Claude Code) framework installer/setup.
|
|
3
|
+
# Runs passport wizard and writes ~/.cursor/hooks.json pointing at the APort hook script.
|
|
4
|
+
# Same hook script works for Cursor, VS Code + Copilot, and Claude Code.
|
|
5
|
+
|
|
6
|
+
LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
|
|
7
|
+
# shellcheck source=../lib/common.sh
|
|
8
|
+
source "$LIB/common.sh"
|
|
9
|
+
# shellcheck source=../lib/passport.sh
|
|
10
|
+
source "$LIB/passport.sh"
|
|
11
|
+
# shellcheck source=../lib/config.sh
|
|
12
|
+
source "$LIB/config.sh"
|
|
13
|
+
|
|
14
|
+
run_setup() {
|
|
15
|
+
log_info "Setting up APort guardrails for Cursor..."
|
|
16
|
+
# Passport and data live under Cursor's config dir (~/.cursor/aport/ by default).
|
|
17
|
+
config_dir="$(get_config_dir cursor)"
|
|
18
|
+
mkdir -p "$config_dir/aport"
|
|
19
|
+
|
|
20
|
+
export APORT_FRAMEWORK=cursor
|
|
21
|
+
run_passport_wizard "$@"
|
|
22
|
+
|
|
23
|
+
# Resolve absolute path to hook script (works from repo or npx package)
|
|
24
|
+
HOOK_SCRIPT="${APORT_CURSOR_HOOK_SCRIPT:-}"
|
|
25
|
+
if [ -z "$HOOK_SCRIPT" ]; then
|
|
26
|
+
ROOT_FOR_HOOK="$(cd "$LIB/../.." && pwd)"
|
|
27
|
+
HOOK_SCRIPT="$ROOT_FOR_HOOK/bin/aport-cursor-hook.sh"
|
|
28
|
+
fi
|
|
29
|
+
if [ ! -f "$HOOK_SCRIPT" ]; then
|
|
30
|
+
log_warn "Hook script not found at $HOOK_SCRIPT; hooks.json will reference it (create the file for hooks to work)."
|
|
31
|
+
else
|
|
32
|
+
HOOK_SCRIPT="$(cd "$(dirname "$HOOK_SCRIPT")" && pwd)/$(basename "$HOOK_SCRIPT")"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Write Cursor hooks config: beforeShellExecution and preToolUse run the same script
|
|
36
|
+
CURSOR_HOOKS_DIR="${CURSOR_HOOKS_DIR:-$HOME/.cursor}"
|
|
37
|
+
CURSOR_HOOKS_FILE="$CURSOR_HOOKS_DIR/hooks.json"
|
|
38
|
+
mkdir -p "$CURSOR_HOOKS_DIR"
|
|
39
|
+
|
|
40
|
+
# Merge with existing hooks.json if present; otherwise create new
|
|
41
|
+
if [ -f "$CURSOR_HOOKS_FILE" ] && command -v jq &> /dev/null; then
|
|
42
|
+
EXISTING=$(cat "$CURSOR_HOOKS_FILE")
|
|
43
|
+
if echo "$EXISTING" | jq -e '.hooks' &> /dev/null; then
|
|
44
|
+
# Add APort hook to beforeShellExecution and preToolUse (avoid duplicate)
|
|
45
|
+
NEW_HOOKS=$(echo "$EXISTING" | jq -c --arg cmd "$HOOK_SCRIPT" '
|
|
46
|
+
(.hooks.beforeShellExecution // []) as $b |
|
|
47
|
+
(.hooks.preToolUse // []) as $p |
|
|
48
|
+
.hooks.beforeShellExecution = ($b | map(select(.command != $cmd)) | . + [{ "command": $cmd }]) |
|
|
49
|
+
.hooks.preToolUse = ($p | map(select(.command != $cmd)) | . + [{ "command": $cmd }])
|
|
50
|
+
')
|
|
51
|
+
echo "$NEW_HOOKS" > "$CURSOR_HOOKS_FILE"
|
|
52
|
+
else
|
|
53
|
+
_write_cursor_hooks_file "$CURSOR_HOOKS_FILE" "$HOOK_SCRIPT"
|
|
54
|
+
fi
|
|
55
|
+
else
|
|
56
|
+
_write_cursor_hooks_file "$CURSOR_HOOKS_FILE" "$HOOK_SCRIPT"
|
|
57
|
+
fi
|
|
58
|
+
|
|
59
|
+
echo ""
|
|
60
|
+
echo " Next steps (Cursor):"
|
|
61
|
+
echo " ────────────────────"
|
|
62
|
+
echo " 1. Hooks config written to: $CURSOR_HOOKS_FILE"
|
|
63
|
+
echo " 2. Hook script: $HOOK_SCRIPT"
|
|
64
|
+
echo " 3. Restart Cursor (or reload window) so hooks are picked up."
|
|
65
|
+
echo " 4. Shell commands and tool use will be checked by APort policy (exit 2 = block)."
|
|
66
|
+
echo ""
|
|
67
|
+
echo " Same script works for VS Code + Copilot and Claude Code — see: docs/frameworks/cursor.md"
|
|
68
|
+
echo ""
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
_write_cursor_hooks_file() {
|
|
72
|
+
local file="$1"
|
|
73
|
+
local cmd="$2"
|
|
74
|
+
if command -v jq &> /dev/null; then
|
|
75
|
+
jq -n -c --arg cmd "$cmd" '{
|
|
76
|
+
version: 1,
|
|
77
|
+
hooks: {
|
|
78
|
+
beforeShellExecution: [{ command: $cmd }],
|
|
79
|
+
preToolUse: [{ command: $cmd }]
|
|
80
|
+
}
|
|
81
|
+
}' > "$file"
|
|
82
|
+
else
|
|
83
|
+
cat > "$file" << EOF
|
|
84
|
+
{
|
|
85
|
+
"version": 1,
|
|
86
|
+
"hooks": {
|
|
87
|
+
"beforeShellExecution": [{"command": "$cmd"}],
|
|
88
|
+
"preToolUse": [{"command": "$cmd"}]
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
EOF
|
|
92
|
+
fi
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
run_setup "$@"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# LangChain/LangGraph framework installer/setup
|
|
3
|
+
# Config: ~/.aport/langchain/ or .aport/config.yaml
|
|
4
|
+
|
|
5
|
+
LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
|
|
6
|
+
# shellcheck source=../lib/common.sh
|
|
7
|
+
source "$LIB/common.sh"
|
|
8
|
+
# shellcheck source=../lib/passport.sh
|
|
9
|
+
source "$LIB/passport.sh"
|
|
10
|
+
# shellcheck source=../lib/config.sh
|
|
11
|
+
source "$LIB/config.sh"
|
|
12
|
+
|
|
13
|
+
run_setup() {
|
|
14
|
+
log_info "Setting up APort guardrails for LangChain..."
|
|
15
|
+
config_dir="$(write_config_template langchain)"
|
|
16
|
+
mkdir -p "$config_dir/aport"
|
|
17
|
+
export APORT_FRAMEWORK=langchain
|
|
18
|
+
run_passport_wizard "$@"
|
|
19
|
+
echo ""
|
|
20
|
+
echo " Next steps (LangChain):"
|
|
21
|
+
echo " ───────────────────────"
|
|
22
|
+
echo " 1. Install the Python adapter (required for runtime enforcement):"
|
|
23
|
+
echo " pip install aport-agent-guardrails-langchain"
|
|
24
|
+
echo " aport-langchain setup"
|
|
25
|
+
echo " 2. Config written to: $config_dir"
|
|
26
|
+
echo " 3. Add to your agent:"
|
|
27
|
+
echo ""
|
|
28
|
+
echo " from aport_guardrails_langchain import APortCallback"
|
|
29
|
+
echo " agent = initialize_agent(..., callbacks=[APortCallback()])"
|
|
30
|
+
echo ""
|
|
31
|
+
echo " See: docs/frameworks/langchain.md"
|
|
32
|
+
echo ""
|
|
33
|
+
# Fail loudly if Python available but adapter not installed (Issue 4); skip in CI/tests
|
|
34
|
+
if [[ -z "${APORT_SKIP_ADAPTER_CHECK:-}" ]]; then
|
|
35
|
+
if command -v pip &> /dev/null || command -v pip3 &> /dev/null; then
|
|
36
|
+
pip_cmd="pip"
|
|
37
|
+
command -v pip3 &> /dev/null && pip_cmd="pip3"
|
|
38
|
+
if ! $pip_cmd show aport-agent-guardrails-langchain &> /dev/null; then
|
|
39
|
+
echo "[aport] ERROR: Python adapter not installed. Run the following, then use your agent:" >&2
|
|
40
|
+
echo " $pip_cmd install aport-agent-guardrails-langchain" >&2
|
|
41
|
+
echo " aport-langchain setup" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
fi
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
run_setup "$@"
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# n8n framework installer/setup
|
|
3
|
+
# Custom node + credentials; config in n8n credentials store.
|
|
4
|
+
#
|
|
5
|
+
# ⚠️ n8n custom node is NOT YET AVAILABLE. This script only runs the passport wizard
|
|
6
|
+
# and writes config. No APort node is installed. See docs/frameworks/n8n.md and
|
|
7
|
+
# DEPLOYMENT_READINESS.md for status.
|
|
8
|
+
|
|
9
|
+
LIB="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")/../lib" && pwd)"
|
|
10
|
+
# shellcheck source=../lib/common.sh
|
|
11
|
+
source "$LIB/common.sh"
|
|
12
|
+
# shellcheck source=../lib/passport.sh
|
|
13
|
+
source "$LIB/passport.sh"
|
|
14
|
+
# shellcheck source=../lib/config.sh
|
|
15
|
+
source "$LIB/config.sh"
|
|
16
|
+
|
|
17
|
+
run_setup() {
|
|
18
|
+
echo " APort n8n support: coming soon. This installer writes config only; custom node not yet available."
|
|
19
|
+
echo ""
|
|
20
|
+
log_info "Setting up APort guardrails for n8n..."
|
|
21
|
+
config_dir="$(write_config_template n8n)"
|
|
22
|
+
mkdir -p "$config_dir/aport"
|
|
23
|
+
export APORT_FRAMEWORK=n8n
|
|
24
|
+
run_passport_wizard "$@"
|
|
25
|
+
echo ""
|
|
26
|
+
echo " Next steps (n8n):"
|
|
27
|
+
echo " ────────────────"
|
|
28
|
+
echo " 1. Install custom node to ~/.n8n/custom/ (or use HTTP Request node to APort API)."
|
|
29
|
+
echo " 2. In your workflow: add APort Guardrail node before action nodes; branch on allow/deny."
|
|
30
|
+
echo " 3. Store agent_id or passport in n8n credentials."
|
|
31
|
+
echo ""
|
|
32
|
+
echo " See: docs/frameworks/n8n.md"
|
|
33
|
+
echo ""
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
run_setup "$@"
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# OpenClaw framework: delegate to full installer so passport wizard, config,
|
|
3
|
+
# plugin, and next steps all run identically (single source of truth in bin/openclaw).
|
|
4
|
+
# Pass-through: all arguments ($@) are passed to bin/openclaw (e.g. agent_id for
|
|
5
|
+
# hosted passport, or any future flags/openclaw options). Non-interactive use
|
|
6
|
+
# (e.g. agent_id only) is unchanged when invoked via agent-guardrails openclaw <agent_id>.
|
|
7
|
+
|
|
8
|
+
# shellcheck source=../lib/common.sh
|
|
9
|
+
source "$(dirname "${BASH_SOURCE[0]:-.}")/../lib/common.sh"
|
|
10
|
+
|
|
11
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)"
|
|
12
|
+
OPENCLAW_BIN="$SCRIPT_DIR/../openclaw"
|
|
13
|
+
|
|
14
|
+
if [[ ! -x "$OPENCLAW_BIN" ]]; then
|
|
15
|
+
log_error "OpenClaw installer not found: $OPENCLAW_BIN"
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
exec "$OPENCLAW_BIN" "$@"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Command allowlisting helpers (shared across frameworks)
|
|
3
|
+
# Used by evaluator / policy to check allowed_commands vs blocked patterns.
|
|
4
|
+
|
|
5
|
+
# shellcheck source=./common.sh
|
|
6
|
+
source "$(dirname "${BASH_SOURCE[0]:-.}")/common.sh"
|
|
7
|
+
|
|
8
|
+
# Placeholder: allowlist check logic can be shared between bash evaluator and API
|
|
9
|
+
# Returns 0 if command is allowed, 1 if denied
|
|
10
|
+
check_command_allowed() {
|
|
11
|
+
local command_line="$1"
|
|
12
|
+
local allowed_list="${2:-*}"
|
|
13
|
+
# TODO: Implement against passport allowed_commands + blocked patterns
|
|
14
|
+
[[ -z "$command_line" ]] && return 1
|
|
15
|
+
return 0
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export -f check_command_allowed
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shared bash functions for APort agent-guardrails (multi-framework)
|
|
3
|
+
# Used by passport wizard, config helpers, and framework installers.
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
# Resolve script directory and project root
|
|
8
|
+
SCRIPT_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)}"
|
|
9
|
+
# Project root: bin/lib -> repo root
|
|
10
|
+
ROOT_DIR="${ROOT_DIR:-$(cd "$SCRIPT_DIR/../.." 2> /dev/null && pwd)}"
|
|
11
|
+
|
|
12
|
+
# Log helpers
|
|
13
|
+
log_info() { echo "[aport] $*" >&2; }
|
|
14
|
+
log_warn() { echo "[aport] WARN: $*" >&2; }
|
|
15
|
+
log_error() { echo "[aport] ERROR: $*" >&2; }
|
|
16
|
+
|
|
17
|
+
# Check required commands
|
|
18
|
+
require_cmd() {
|
|
19
|
+
local cmd="$1"
|
|
20
|
+
if ! command -v "$cmd" &> /dev/null; then
|
|
21
|
+
log_error "Required command not found: $cmd"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
# Export for subshells
|
|
27
|
+
export SCRIPT_DIR ROOT_DIR
|
|
28
|
+
export -f log_info log_warn log_error require_cmd
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Config file management (shared across frameworks)
|
|
3
|
+
# Read/write config, env vars, credential paths.
|
|
4
|
+
|
|
5
|
+
# shellcheck source=./common.sh
|
|
6
|
+
source "$(dirname "${BASH_SOURCE[0]:-.}")/common.sh"
|
|
7
|
+
|
|
8
|
+
# Default config locations per framework (where that framework stores data; can be overridden by env).
|
|
9
|
+
# Default passport path = get_config_dir/aport/passport.json. Keep in sync with packages/core default-passport-paths.json.
|
|
10
|
+
get_config_dir() {
|
|
11
|
+
local framework="${1:-}"
|
|
12
|
+
case "$framework" in
|
|
13
|
+
openclaw) echo "${APORT_OPENCLAW_CONFIG_DIR:-$HOME/.openclaw}" ;;
|
|
14
|
+
langchain) echo "${APORT_LANGCHAIN_CONFIG_DIR:-$HOME/.aport/langchain}" ;;
|
|
15
|
+
crewai) echo "${APORT_CREWAI_CONFIG_DIR:-$HOME/.aport/crewai}" ;;
|
|
16
|
+
n8n) echo "${APORT_N8N_CONFIG_DIR:-$HOME/.n8n}" ;;
|
|
17
|
+
cursor) echo "${APORT_CURSOR_CONFIG_DIR:-$HOME/.cursor}" ;;
|
|
18
|
+
*) echo "${APORT_CONFIG_DIR:-$HOME/.aport}" ;;
|
|
19
|
+
esac
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Default passport path per framework (config_dir/aport/passport.json). Used by wizard and evaluator.
|
|
23
|
+
get_default_passport_path() {
|
|
24
|
+
local framework="${1:-}"
|
|
25
|
+
local config_dir
|
|
26
|
+
config_dir="$(get_config_dir "$framework")"
|
|
27
|
+
config_dir="${config_dir/#\~/$HOME}"
|
|
28
|
+
echo "${config_dir}/aport/passport.json"
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
write_config_template() {
|
|
32
|
+
local framework="$1"
|
|
33
|
+
local dest_dir
|
|
34
|
+
dest_dir="$(get_config_dir "$framework")"
|
|
35
|
+
mkdir -p "$dest_dir"
|
|
36
|
+
log_info "Config directory: $dest_dir"
|
|
37
|
+
local lib_dir templates_dir
|
|
38
|
+
lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]:-.}")" && pwd)"
|
|
39
|
+
templates_dir="$lib_dir/templates"
|
|
40
|
+
if [[ -f "$templates_dir/config.yaml" ]]; then
|
|
41
|
+
cp "$templates_dir/config.yaml" "$dest_dir/config.yaml" 2> /dev/null || true
|
|
42
|
+
fi
|
|
43
|
+
echo "$dest_dir"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export -f get_config_dir get_default_passport_path write_config_template
|