@goplus/agentguard 1.0.14 → 1.1.3

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.
Files changed (91) hide show
  1. package/README.md +33 -2
  2. package/dist/cli.d.ts +3 -0
  3. package/dist/cli.d.ts.map +1 -0
  4. package/dist/cli.js +172 -0
  5. package/dist/cli.js.map +1 -0
  6. package/dist/cloud/client.d.ts +19 -0
  7. package/dist/cloud/client.d.ts.map +1 -0
  8. package/dist/cloud/client.js +86 -0
  9. package/dist/cloud/client.js.map +1 -0
  10. package/dist/config.d.ts +31 -0
  11. package/dist/config.d.ts.map +1 -0
  12. package/dist/config.js +131 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/index.d.ts +7 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +25 -1
  17. package/dist/index.js.map +1 -1
  18. package/dist/installers.d.ts +10 -0
  19. package/dist/installers.d.ts.map +1 -0
  20. package/dist/installers.js +137 -0
  21. package/dist/installers.js.map +1 -0
  22. package/dist/mcp-server.js +3 -2
  23. package/dist/mcp-server.js.map +1 -1
  24. package/dist/postinstall.d.ts +3 -0
  25. package/dist/postinstall.d.ts.map +1 -0
  26. package/dist/postinstall.js +13 -0
  27. package/dist/postinstall.js.map +1 -0
  28. package/dist/runtime/audit.d.ts +10 -0
  29. package/dist/runtime/audit.d.ts.map +1 -0
  30. package/dist/runtime/audit.js +94 -0
  31. package/dist/runtime/audit.js.map +1 -0
  32. package/dist/runtime/evaluator.d.ts +3 -0
  33. package/dist/runtime/evaluator.d.ts.map +1 -0
  34. package/dist/runtime/evaluator.js +197 -0
  35. package/dist/runtime/evaluator.js.map +1 -0
  36. package/dist/runtime/policy.d.ts +12 -0
  37. package/dist/runtime/policy.d.ts.map +1 -0
  38. package/dist/runtime/policy.js +81 -0
  39. package/dist/runtime/policy.js.map +1 -0
  40. package/dist/runtime/protect.d.ts +22 -0
  41. package/dist/runtime/protect.d.ts.map +1 -0
  42. package/dist/runtime/protect.js +172 -0
  43. package/dist/runtime/protect.js.map +1 -0
  44. package/dist/runtime/redaction.d.ts +6 -0
  45. package/dist/runtime/redaction.d.ts.map +1 -0
  46. package/dist/runtime/redaction.js +103 -0
  47. package/dist/runtime/redaction.js.map +1 -0
  48. package/dist/runtime/types.d.ts +62 -0
  49. package/dist/runtime/types.d.ts.map +1 -0
  50. package/dist/runtime/types.js +3 -0
  51. package/dist/runtime/types.js.map +1 -0
  52. package/dist/scanner/rules/trojan.js +1 -1
  53. package/dist/scanner/rules/trojan.js.map +1 -1
  54. package/dist/tests/cloud-live.test.d.ts +2 -0
  55. package/dist/tests/cloud-live.test.d.ts.map +1 -0
  56. package/dist/tests/cloud-live.test.js +68 -0
  57. package/dist/tests/cloud-live.test.js.map +1 -0
  58. package/dist/tests/installer.test.d.ts +2 -0
  59. package/dist/tests/installer.test.d.ts.map +1 -0
  60. package/dist/tests/installer.test.js +32 -0
  61. package/dist/tests/installer.test.js.map +1 -0
  62. package/dist/tests/runtime-cloud.test.d.ts +2 -0
  63. package/dist/tests/runtime-cloud.test.d.ts.map +1 -0
  64. package/dist/tests/runtime-cloud.test.js +202 -0
  65. package/dist/tests/runtime-cloud.test.js.map +1 -0
  66. package/dist/version.d.ts +2 -0
  67. package/dist/version.d.ts.map +1 -0
  68. package/dist/version.js +7 -0
  69. package/dist/version.js.map +1 -0
  70. package/docs/SECURITY-POLICY.md +558 -0
  71. package/docs/architecture.md +54 -0
  72. package/docs/claude-code.md +41 -0
  73. package/docs/cloud-connect.md +73 -0
  74. package/docs/cloud-native-api.md +526 -0
  75. package/docs/codex.md +38 -0
  76. package/docs/goplus-api.md +38 -0
  77. package/docs/mcp-server.md +39 -0
  78. package/docs/openclaw.md +41 -0
  79. package/docs/privacy-boundary.md +37 -0
  80. package/docs/sdk.md +83 -0
  81. package/docs/trust-cli.md +58 -0
  82. package/examples/openclaw-docker/Dockerfile +10 -0
  83. package/examples/openclaw-docker/README.md +16 -0
  84. package/examples/openclaw-docker/docker-compose.yml +8 -0
  85. package/examples/openclaw-docker/plugin.ts +8 -0
  86. package/package.json +7 -2
  87. package/skills/agentguard/SKILL.md +157 -61
  88. package/skills/agentguard/{scripts/package.json → package.json} +2 -1
  89. package/skills/agentguard/patrol-checks.md +12 -2
  90. package/skills/agentguard/scan-rules.md +1 -1
  91. package/skills/agentguard/scripts/checkup-report.js +71 -30
@@ -0,0 +1,41 @@
1
+ # OpenClaw
2
+
3
+ OpenClaw can use AgentGuard as a local runtime guard and optional Cloud-connected audit source.
4
+
5
+ ## Plugin usage
6
+
7
+ To write a starter plugin file in the current project:
8
+
9
+ ```bash
10
+ agentguard init --agent openclaw
11
+ ```
12
+
13
+ This creates `openclaw.agentguard.plugin.ts`.
14
+
15
+ ```ts
16
+ import { registerOpenClawPlugin } from '@goplus/agentguard';
17
+
18
+ export default function setup(api) {
19
+ registerOpenClawPlugin(api, {
20
+ level: 'balanced',
21
+ skipAutoScan: false,
22
+ });
23
+ }
24
+ ```
25
+
26
+ ## Runtime hook shape
27
+
28
+ For direct hook integration, send events to:
29
+
30
+ ```bash
31
+ AGENTGUARD_AGENT_HOST=openclaw \
32
+ AGENTGUARD_ACTION_TYPE=shell \
33
+ AGENTGUARD_TOOL_NAME=exec \
34
+ agentguard protect
35
+ ```
36
+
37
+ AgentGuard accepts OpenClaw-style JSON with `toolName` and `params`, plus Claude-style `tool_name` and `tool_input`.
38
+
39
+ ## Docker demo
40
+
41
+ See `examples/openclaw-docker/` for a minimal Docker demo that installs `@goplus/agentguard`, runs `agentguard init --agent openclaw`, and provides a starter plugin.
@@ -0,0 +1,37 @@
1
+ # OSS / Cloud Privacy Boundary
2
+
3
+ AgentGuard OSS protects your machine without requiring a Cloud account.
4
+
5
+ ## Stays local by default
6
+
7
+ - Full prompts
8
+ - Full file contents
9
+ - Full command output
10
+ - Full secrets and private keys
11
+ - Local audit file at `~/.agentguard/audit.jsonl`
12
+ - Cached policy at `~/.agentguard/policy-cache.json`
13
+
14
+ ## Sent to Cloud when connected
15
+
16
+ Only redacted runtime audit previews are uploaded by default:
17
+
18
+ - `sessionId`, `agentHost`, `actionType`, `toolName`
19
+ - Redacted `input` preview, capped at 2,000 characters
20
+ - Decision, risk score, risk level, reasons, and policy version
21
+ - Optional approval request metadata for `require_approval`
22
+
23
+ ## Built-in redaction
24
+
25
+ AgentGuard redacts common sensitive values before Cloud sync:
26
+
27
+ - AgentGuard/OpenAI-style API keys
28
+ - `Bearer` tokens
29
+ - `token=`, `api_key=`, `secret=`, `password=`, and similar query/env values
30
+ - Private key PEM blocks
31
+ - URL credentials and sensitive query parameters
32
+
33
+ Cloud endpoints also apply server-side redaction, but clients should not rely on server redaction as the first line of defense.
34
+
35
+ ## Offline behavior
36
+
37
+ If Cloud is unreachable, AgentGuard continues local enforcement and spools redacted audit events for later retry. It must never fail open for local `block` decisions.
package/docs/sdk.md ADDED
@@ -0,0 +1,83 @@
1
+ # SDK Usage
2
+
3
+ Use GoPlus AgentGuard as a library in your own project.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @goplus/agentguard
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createAgentGuard } from '@goplus/agentguard';
15
+
16
+ const { scanner, registry, actionScanner } = createAgentGuard();
17
+ ```
18
+
19
+ ## Scan Code
20
+
21
+ ```typescript
22
+ const result = await scanner.scan({
23
+ skill: {
24
+ id: 'my-skill',
25
+ source: 'github.com/org/skill',
26
+ version_ref: 'v1.0.0',
27
+ artifact_hash: '',
28
+ },
29
+ payload: { type: 'dir', ref: '/path/to/skill' },
30
+ });
31
+
32
+ console.log(result.risk_level); // 'low' | 'medium' | 'high' | 'critical'
33
+ console.log(result.hits); // Array of detection rule matches
34
+ ```
35
+
36
+ ## Evaluate Actions
37
+
38
+ ```typescript
39
+ const decision = await actionScanner.decide({
40
+ actor: {
41
+ skill: { id: 'my-skill', source: 'cli', version_ref: '1.0.0', artifact_hash: '' },
42
+ },
43
+ action: {
44
+ type: 'exec_command',
45
+ data: { command: 'rm -rf /' },
46
+ },
47
+ context: {
48
+ session_id: 's1',
49
+ user_present: true,
50
+ env: 'prod',
51
+ time: new Date().toISOString(),
52
+ },
53
+ });
54
+
55
+ console.log(decision.decision); // 'allow' | 'deny' | 'confirm'
56
+ ```
57
+
58
+ ## Trust Registry
59
+
60
+ ```typescript
61
+ // Register a skill
62
+ await registry.attest({
63
+ skill: { id: 'bot', source: 'github.com/org/bot', version_ref: 'v1.0.0', artifact_hash: 'sha256:abc' },
64
+ trust_level: 'trusted',
65
+ capabilities: { network_allowlist: ['api.example.com'], filesystem_allowlist: [], exec: 'deny', secrets_allowlist: [] },
66
+ review: { reviewed_by: 'admin', evidence_refs: [], notes: 'Verified safe' },
67
+ });
68
+
69
+ // Look up
70
+ const result = await registry.lookup({
71
+ id: 'bot', source: 'github.com/org/bot', version_ref: 'v1.0.0', artifact_hash: 'sha256:abc',
72
+ });
73
+ console.log(result.effective_trust_level); // 'trusted'
74
+ ```
75
+
76
+ ## API Reference
77
+
78
+ See the TypeScript types exported from `@goplus/agentguard` for full API details:
79
+
80
+ - `SkillScanner` — Static analysis engine
81
+ - `SkillRegistry` — Trust level management
82
+ - `ActionScanner` — Runtime action evaluator
83
+ - `CAPABILITY_PRESETS` — Predefined capability sets (none, read_only, trading_bot, defi)
@@ -0,0 +1,58 @@
1
+ # Trust Management
2
+
3
+ GoPlus AgentGuard includes a trust registry for managing skill permissions.
4
+
5
+ ## Commands
6
+
7
+ ### Attest (Register a Skill)
8
+
9
+ ```
10
+ /agentguard trust attest --id my-bot --source github.com/org/bot --version v1.0.0 --hash abc --trust-level restricted --preset trading_bot --reviewed-by admin
11
+ ```
12
+
13
+ ### Lookup
14
+
15
+ ```
16
+ /agentguard trust lookup --source github.com/org/bot
17
+ ```
18
+
19
+ ### Revoke
20
+
21
+ ```
22
+ /agentguard trust revoke --source github.com/org/bot --reason "security concern"
23
+ ```
24
+
25
+ ### List
26
+
27
+ ```
28
+ /agentguard trust list --trust-level trusted
29
+ ```
30
+
31
+ ## Trust Levels
32
+
33
+ | Level | Description |
34
+ |-------|-------------|
35
+ | `trusted` | Full access per its capability model |
36
+ | `restricted` | Limited access, some actions require confirmation |
37
+ | `untrusted` | Minimal access, most actions blocked or require confirmation |
38
+
39
+ ## Capability Presets
40
+
41
+ | Preset | Network | Filesystem | Exec | Secrets | Web3 |
42
+ |--------|---------|------------|------|---------|------|
43
+ | `none` | No | No | No | No | No |
44
+ | `read_only` | No | Read `./**` | No | No | No |
45
+ | `trading_bot` | Binance, Bybit, OKX, Coinbase, Dextools, CoinGecko | `./config/**`, `./logs/**` | No | `*_API_KEY`, `*_API_SECRET` | Chains 1, 56, 137, 42161 |
46
+ | `defi` | All | No | No | No | Chains 1, 56, 137, 42161, 10, 8453, 43114 |
47
+
48
+ ## Auto-Scan on Session Start
49
+
50
+ When installed as a Claude Code plugin, AgentGuard automatically scans new skills on session start:
51
+
52
+ - Discovers skills in `~/.claude/skills/`
53
+ - Calculates artifact hash and checks the registry
54
+ - Runs `quickScan` on new or updated skills
55
+ - Auto-registers with trust level based on scan results:
56
+ - Low risk → `trusted`
57
+ - Medium risk → `restricted`
58
+ - High/Critical risk → `untrusted`
@@ -0,0 +1,10 @@
1
+ FROM node:22-slim
2
+
3
+ WORKDIR /workspace
4
+
5
+ RUN npm install -g @goplus/agentguard
6
+ RUN agentguard init --agent openclaw
7
+
8
+ COPY plugin.ts ./plugin.ts
9
+
10
+ CMD ["node", "-e", "console.log('AgentGuard OpenClaw demo ready. Mount your OpenClaw workspace and register plugin.ts.')"]
@@ -0,0 +1,16 @@
1
+ # OpenClaw Docker Demo
2
+
3
+ This demo shows the minimal AgentGuard runtime wiring for OpenClaw.
4
+
5
+ ```bash
6
+ docker compose build
7
+ docker compose run --rm agentguard-openclaw-demo
8
+ ```
9
+
10
+ In a real OpenClaw workspace, register `plugin.ts` as a plugin. It uses `registerOpenClawPlugin` to scan loaded skills/plugins and evaluate runtime tool calls before execution.
11
+
12
+ For Cloud policy and audit sync:
13
+
14
+ ```bash
15
+ AGENTGUARD_API_KEY=ag_live_xxxxx agentguard connect --url https://agentguard.gopluslabs.io
16
+ ```
@@ -0,0 +1,8 @@
1
+ services:
2
+ agentguard-openclaw-demo:
3
+ build: .
4
+ working_dir: /workspace
5
+ volumes:
6
+ - .:/workspace/demo
7
+ environment:
8
+ AGENTGUARD_AGENT_HOST: openclaw
@@ -0,0 +1,8 @@
1
+ import { registerOpenClawPlugin } from '@goplus/agentguard';
2
+
3
+ export default function setup(api) {
4
+ registerOpenClawPlugin(api, {
5
+ level: 'balanced',
6
+ skipAutoScan: false,
7
+ });
8
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@goplus/agentguard",
3
- "version": "1.0.14",
3
+ "version": "1.1.3",
4
4
  "description": "GoPlus AgentGuard — Security guard for AI agents. Blocks dangerous commands, prevents data leaks, protects secrets. 20 detection rules, runtime action evaluation, trust registry.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -10,13 +10,16 @@
10
10
  ]
11
11
  },
12
12
  "bin": {
13
- "agentguard": "./dist/mcp-server.js"
13
+ "agentguard": "./dist/cli.js",
14
+ "agentguard-mcp": "./dist/mcp-server.js"
14
15
  },
15
16
  "scripts": {
16
17
  "build": "tsc",
17
18
  "start": "node dist/mcp-server.js",
18
19
  "dev": "tsc -w",
19
20
  "test": "node --test dist/tests/*.test.js",
21
+ "test:cloud-live": "node --test dist/tests/cloud-live.test.js",
22
+ "postinstall": "node dist/postinstall.js || true",
20
23
  "prepublishOnly": "npm run build"
21
24
  },
22
25
  "keywords": [
@@ -59,6 +62,8 @@
59
62
  },
60
63
  "files": [
61
64
  "dist",
65
+ "docs",
66
+ "examples/openclaw-docker",
62
67
  "README.md",
63
68
  "LICENSE",
64
69
  "openclaw.plugin.json",
@@ -1,14 +1,33 @@
1
1
  ---
2
2
  name: agentguard
3
- description: GoPlus AgentGuard — AI agent security guard. Run /agentguard checkup for a full security health check: scans all installed skills, checks credentials, permissions, and network exposure, then delivers an HTML report directly to you. Also use for scanning third-party code, blocking dangerous commands, preventing data leaks, evaluating action safety, and running daily security patrols.
3
+ description: GoPlus AgentGuard — AI agent security guard. Run /agentguard checkup for a full security health check, scans all installed skills, checks credentials, permissions, and network exposure, then delivers an HTML report directly to you. Also use for scanning third-party code, blocking dangerous commands, preventing data leaks, evaluating action safety, and running daily security patrols.
4
4
  license: MIT
5
5
  compatibility: Requires Node.js 18+. Optional GoPlus API credentials for enhanced Web3 simulation.
6
6
  metadata:
7
7
  author: GoPlusSecurity
8
8
  version: "1.1"
9
9
  optional_env: "GOPLUS_API_KEY, GOPLUS_API_SECRET (for Web3 transaction simulation only)"
10
+ filesystem-access:
11
+ - path: "~/.ssh/"
12
+ access: read-only
13
+ reason: "Credential safety audit — check directory permissions (stat only, no key content read)"
14
+ - path: "~/.gnupg/"
15
+ access: read-only
16
+ reason: "Credential safety audit — check directory permissions (stat only)"
17
+ - path: "~/.claude/"
18
+ access: read-only
19
+ reason: "Discover installed skills and read security hook configuration"
20
+ - path: "~/.openclaw/"
21
+ access: read-only
22
+ reason: "Discover installed skills and read OpenClaw config for patrol checks"
23
+ - path: "~/.qclaw/"
24
+ access: read-only
25
+ reason: "Discover installed skills in QClaw environments"
26
+ - path: "~/.agentguard/"
27
+ access: read-write
28
+ reason: "Read/write audit log (audit.jsonl) and protection level config (config.json)"
10
29
  user-invocable: true
11
- allowed-tools: Read, Grep, Glob, Bash(node *trust-cli.ts *) Bash(node *action-cli.ts *) Bash(*checkup-report.js) Bash(echo *checkup-report.js) Bash(cat *checkup-report.js) Bash(openclaw *) Bash(ss *) Bash(lsof *) Bash(ufw *) Bash(iptables *) Bash(crontab *) Bash(systemctl list-timers *) Bash(find *) Bash(stat *) Bash(env) Bash(sha256sum *) Bash(node *) Bash(cd *)
30
+ allowed-tools: Read, Write, Grep, Glob, Bash(node *trust-cli.ts *) Bash(node *action-cli.ts *) Bash(*checkup-report.js) Bash(echo *checkup-report.js) Bash(cat *checkup-report.js) Bash(openclaw *) Bash(ss *) Bash(lsof *) Bash(ufw *) Bash(iptables *) Bash(crontab *) Bash(systemctl list-timers *) Bash(find *) Bash(stat *) Bash(env) Bash(sha256sum *) Bash(node *) Bash(cd *)
12
31
  argument-hint: "[scan|action|patrol|trust|report|config|checkup] [args...]"
13
32
  ---
14
33
 
@@ -89,7 +108,7 @@ For each rule, use Grep to search the relevant file types. Record every match wi
89
108
  | 21 | TROJAN_DISTRIBUTION | CRITICAL | md | Trojanized binary download + password + execute |
90
109
  | 22 | SUSPICIOUS_PASTE_URL | HIGH | all | URLs to paste sites (pastebin, glot.io, etc.) |
91
110
  | 23 | SUSPICIOUS_IP | MEDIUM | all | Hardcoded public IPv4 addresses |
92
- | 24 | SOCIAL_ENGINEERING | MEDIUM | md | Pressure language + execution instructions |
111
+ | 24 | SOCIAL_ENGINEERING | HIGH | md | Pressure language + execution instructions |
93
112
 
94
113
  ### Risk Level Calculation
95
114
 
@@ -284,7 +303,7 @@ Detect tampered or unregistered skill packages by comparing file hashes against
284
303
  Scan workspace files for leaked secrets using AgentGuard's own detection patterns.
285
304
 
286
305
  **Steps**:
287
- 1. Use Grep to scan `$OC/workspace/` (especially `memory/` and `logs/`) with patterns from:
306
+ 1. Use Grep to scan `$OC/workspace/` **recursively, covering all agent subdirectories** (e.g. all `workspace-agent-*/` directories, not just the current agent's workspace) with patterns from:
288
307
  - scan-rules.md Rule 7 (PRIVATE_KEY_PATTERN): `0x[a-fA-F0-9]{64}` in quotes
289
308
  - scan-rules.md Rule 8 (MNEMONIC_PATTERN): BIP-39 word sequences, `seed_phrase`, `mnemonic`
290
309
  - scan-rules.md Rule 5 (READ_SSH_KEYS): SSH key file references in workspace
@@ -610,89 +629,129 @@ Run a comprehensive agent health checkup across 6 security dimensions. Generates
610
629
 
611
630
  ### Step 1: Data Collection
612
631
 
632
+ **IMPORTANT: You MUST run ALL 7 checks below — not just the skill scan. The checkup covers 5 security dimensions, not just code scanning. Do NOT skip checks 2–7.**
633
+
613
634
  Run these checks in parallel where possible. These are **universal agent security checks** — they apply to any Claude Code or OpenClaw environment, regardless of whether AgentGuard is installed.
614
635
 
615
- 1. **Discover & scan installed skills**: Glob `~/.claude/skills/*/SKILL.md` and `~/.openclaw/skills/*/SKILL.md`. For each discovered skill, **run `/agentguard scan <skill_path>`** using the scan subcommand logic (24 detection rules). Collect the scan results (risk level, findings count, risk tags) for each skill.
616
- 2. **Credential file permissions**: `stat` on `~/.ssh/`, `~/.gnupg/`, and if OpenClaw: `stat` on `$OC/openclaw.json`, `$OC/devices/paired.json`
617
- 3. **Sensitive credential scan (DLP)**: Use Grep to scan workspace memory/logs directories for leaked secrets:
618
- - Private keys: `0x[a-fA-F0-9]{64}`, `-----BEGIN.*PRIVATE KEY-----`
619
- - Mnemonics: sequences of 12+ BIP-39 words, `seed_phrase`, `mnemonic`
620
- - API keys/tokens: `AKIA[0-9A-Z]{16}`, `gh[pousr]_[A-Za-z0-9_]{36}`, plaintext passwords
621
- 4. **Network exposure**: Run `lsof -i -P -n 2>/dev/null | grep LISTEN` or `ss -tlnp 2>/dev/null` to check for dangerous open ports (Redis 6379, Docker API 2375, MySQL 3306, MongoDB 27017 on 0.0.0.0)
622
- 5. **Scheduled tasks audit**: Check `crontab -l 2>/dev/null` for suspicious entries containing `curl|bash`, `wget|sh`, or accessing `~/.ssh/`
623
- 6. **Environment variable exposure**: Run `env` and check for sensitive variable names (`PRIVATE_KEY`, `MNEMONIC`, `SECRET`, `PASSWORD`) detect presence only, mask values
624
- 7. **Runtime protection check**: Check if security hooks exist in `~/.claude/settings.json`, check for audit logs at `~/.agentguard/audit.jsonl`
636
+ 1. **[REQUIRED] Discover & scan installed skills** (→ feeds Dimension 1: Code Safety): Glob ALL of the following paths for `*/SKILL.md`:
637
+ - `~/.claude/skills/*/SKILL.md`
638
+ - `~/.openclaw/skills/*/SKILL.md`
639
+ - `~/.openclaw/workspace/skills/*/SKILL.md`
640
+ - `~/.qclaw/skills/*/SKILL.md`
641
+ - `~/.qclaw/workspace/skills/*/SKILL.md`
642
+
643
+ For **every** discovered skill, **run `/agentguard scan <skill_path>`** using the scan subcommand logic (24 detection rules). Do NOT skip any skill regardless of how many are found. Collect the scan results (risk level, findings count, risk tags) for each skill.
644
+ 2. **[REQUIRED] Credential file permissions** (→ feeds Dimension 2: Credential Safety): Platform-aware checkbehavior differs by OS:
645
+ - **macOS/Linux**: Run `stat -f '%Lp' <path> 2>/dev/null || stat -c '%a' <path> 2>/dev/null` on `~/.ssh/`, `~/.gnupg/`, and if OpenClaw: on `$OC/openclaw.json`, `$OC/devices/paired.json`. **If the command returns empty output, the directory does not exist — treat as N/A (award full points), do NOT flag as a failure.**
646
+ - **Windows**: `stat` is not available. Use `icacls <path>` to check ACLs instead. If the directory does not exist, treat as N/A (award full points). If it exists, check that the ACL grants access only to the current user (no `Everyone`, `Users`, or `Authenticated Users` with write/read access). Flag as FAIL only if the directory exists AND the ACL is overly permissive.
647
+ 3. **[REQUIRED] Sensitive credential scan / DLP** (→ feeds Dimension 2: Credential Safety): Use Grep to scan **all** agent workspace directories for leaked secrets. This MUST cover the entire workspace root, not just the current agent's directory:
648
+ - For OpenClaw / QClaw: scan `~/.openclaw/workspace/` and `~/.qclaw/workspace/` recursively — this includes **all** `workspace-agent-*/` subdirectories, not just the current agent's workspace
649
+ - For Claude Code: scan `~/.claude/` recursively
650
+ - Patterns to detect:
651
+ - Private keys: `0x[a-fA-F0-9]{64}`, `-----BEGIN.*PRIVATE KEY-----`
652
+ - Mnemonics: sequences of 12+ BIP-39 words, `seed_phrase`, `mnemonic`
653
+ - API keys/tokens: `AKIA[0-9A-Z]{16}`, `gh[pousr]_[A-Za-z0-9_]{36}`, plaintext passwords
654
+ - **Important**: Use the workspace *root* directory as the scan target (e.g. `~/.qclaw/workspace/`), not a specific agent subdirectory. All sibling `workspace-agent-*` directories must be included.
655
+ 4. **[REQUIRED] Network exposure** (→ feeds Dimension 3: Network & System): Run `lsof -i -P -n 2>/dev/null | grep LISTEN` or `ss -tlnp 2>/dev/null` to check for dangerous open ports (Redis 6379, Docker API 2375, MySQL 3306, MongoDB 27017 on 0.0.0.0)
656
+ 5. **[REQUIRED] Scheduled tasks audit** (→ feeds Dimension 3: Network & System): Check `crontab -l 2>/dev/null` for suspicious entries containing `curl|bash`, `wget|sh`, or accessing `~/.ssh/`
657
+ 6. **[REQUIRED] Environment variable exposure** (→ feeds Dimension 3: Network & System): Run `env` and check for sensitive variable names (`PRIVATE_KEY`, `MNEMONIC`, `SECRET`, `PASSWORD`) — detect presence only, mask values
658
+ 7. **[REQUIRED] Runtime protection check** (→ feeds Dimension 4: Runtime Protection): Check if security hooks exist in `~/.claude/settings.json` or `~/.openclaw/openclaw.json`, check for audit logs at `~/.agentguard/audit.jsonl`
625
659
 
626
660
  ### Step 2: Score Calculation
627
661
 
628
- Checklist-based scoring across 6 security dimensions. **Every failed check = 1 finding with severity and description.**
662
+ **Additive scoring**: Each dimension starts at **0**. For each check that **passes**, add the listed points. Maximum is 100 per dimension. **Every failed check = 1 finding with severity and description.**
629
663
 
630
664
  #### Dimension 1: Skill & Code Safety (weight: 25%)
631
665
 
632
- Uses AgentGuard's 24-rule scan engine (`/agentguard scan`) to audit each installed skill.
666
+ Uses AgentGuard's 24-rule scan engine (`/agentguard scan`) to audit each installed skill. Start at base 100 and **deduct** for findings:
667
+
668
+ - Base score: **100**
669
+ - Each CRITICAL finding: **−15**
670
+ - Each HIGH finding: **−8**
671
+ - Each MEDIUM finding: **−3**
672
+ - Floor at **0** (never negative)
633
673
 
634
- | Check | Score | If failed finding |
635
- |-------|-------|---------------------|
636
- | All skills scanned with risk level LOW | +40 | For each skill with findings, add per-finding: "<rule_id> in <skill>:<file>:<line>" with its severity |
637
- | No CRITICAL scan findings across all skills | +30 | "CRITICAL: <rule_id> detected in <skill>" (CRITICAL) |
638
- | No HIGH scan findings across all skills | +30 | "HIGH: <rule_id> detected in <skill>" (HIGH) |
674
+ For each finding, add: `"<rule_id> in <skill>:<file>:<line>"` with its severity.
639
675
 
640
- Deductions from base 100: each CRITICAL finding −15, HIGH −8, MEDIUM −3. Floor at 0.
676
+ **False-positive suppression**: When the scanned skill is `agentguard` itself (skill path contains `agentguard`), suppress `READ_ENV_SECRETS` findings — AgentGuard reads environment variables as part of its own configuration detection, which is expected behaviour and not a security risk. Do not deduct points or list these as findings in the report.
641
677
 
642
- If no skills installed: score = 70, add finding: "No third-party skills installed — no code to audit" (LOW).
678
+ If no skills installed: score = **70**, add finding: "No third-party skills installed — no code to audit" (LOW).
643
679
 
644
680
  #### Dimension 2: Credential & Secret Safety (weight: 25%)
645
681
 
646
- Checks for leaked credentials and permission hygiene.
682
+ Checks for leaked credentials and permission hygiene. Start at **0**, add points for each check that **passes** (total possible = 100):
647
683
 
648
- | Check | Score | If failed → finding |
649
- |-------|-------|---------------------|
650
- | `~/.ssh/` permissions are 700 or stricter | +25 | "~/.ssh/ permissions too open (<actual>) — should be 700" (HIGH) |
651
- | `~/.gnupg/` permissions are 700 or stricter | +15 | "~/.gnupg/ permissions too open (<actual>) — should be 700" (MEDIUM) |
652
- | No private keys (hex 0x..64, PEM) found in skill code or workspace | +25 | "Plaintext private key found in <location>" (CRITICAL) |
653
- | No mnemonic phrases found in skill code or workspace | +20 | "Plaintext mnemonic found in <location>" (CRITICAL) |
654
- | No API keys/tokens (AWS AKIA.., GitHub gh*_) found in skill code | +15 | "API key/token found in <location>" (HIGH) |
684
+ | Check | Points if PASS | If FAIL → finding |
685
+ |-------|---------------|-------------------|
686
+ | `~/.ssh/` permissions are 700 or stricter | **+25** | "~/.ssh/ permissions too open (<actual>) — should be 700" (HIGH) |
687
+ | `~/.gnupg/` permissions are 700 or stricter | **+15** | "~/.gnupg/ permissions too open (<actual>) — should be 700" (MEDIUM) |
688
+
689
+ **Permission check rules (to avoid false positives):**
690
+ - **Directory does not exist** (stat/icacls returns empty or "file not found"): Treat as N/A award the points. A missing `~/.ssh/` or `~/.gnupg/` is not a security risk.
691
+ - **Windows**: Use `icacls` instead of `stat`. Award full points if directory doesn't exist. Flag as FAIL only if directory exists AND ACL grants access to `Everyone`, `Users`, or `Authenticated Users`.
692
+ - **macOS/Linux**: Flag as FAIL only when the directory exists AND stat returns a numeric value AND that value is greater than 700.
693
+ | No private keys (hex 0x..64, PEM) found in skill code or workspace | **+25** | "Plaintext private key found in <location>" (CRITICAL) |
694
+ | No mnemonic phrases found in skill code or workspace | **+20** | "Plaintext mnemonic found in <location>" (CRITICAL) |
695
+ | No API keys/tokens (AWS AKIA.., GitHub gh*_) found in skill code | **+15** | "API key/token found in <location>" (HIGH) |
655
696
 
656
697
  #### Dimension 3: Network & System Exposure (weight: 20%)
657
698
 
658
- Checks for dangerous network exposure and system-level risks.
699
+ Checks for dangerous network exposure and system-level risks. Start at **0**, add points for each check that **passes** (total possible = 100):
700
+
701
+ | Check | Points if PASS | If FAIL → finding |
702
+ |-------|---------------|-------------------|
703
+ | No high-risk ports exposed on 0.0.0.0 (Redis/Docker/MySQL/MongoDB) | **+35** | "Dangerous port exposed: <service> on 0.0.0.0:<port>" (HIGH) |
704
+ | No suspicious cron jobs (curl\|bash, wget\|sh, accessing ~/.ssh/) | **+30** | "Suspicious cron job: <command>" (HIGH) |
705
+ | No sensitive env vars with dangerous names (PRIVATE_KEY, MNEMONIC) | **+20** | "Sensitive env var exposed: <name>" (MEDIUM) |
706
+ | OpenClaw config files have proper permissions (600) if applicable | **+15** | "OpenClaw config <file> permissions too open" (MEDIUM) |
659
707
 
660
- | Check | Score | If failedfinding |
661
- |-------|-------|---------------------|
662
- | No high-risk ports exposed on 0.0.0.0 (Redis/Docker/MySQL/MongoDB) | +35 | "Dangerous port exposed: <service> on 0.0.0.0:<port>" (HIGH) |
663
- | No suspicious cron jobs (curl\|bash, wget\|sh, accessing ~/.ssh/) | +30 | "Suspicious cron job: <command>" (HIGH) |
664
- | No sensitive env vars with dangerous names (PRIVATE_KEY, MNEMONIC) | +20 | "Sensitive env var exposed: <name>" (MEDIUM) |
665
- | OpenClaw config files have proper permissions (600) if applicable | +15 | "OpenClaw config <file> permissions too open" (MEDIUM) |
708
+ **Example**: If no dangerous ports (+35), no suspicious cron (+30), but env var `PRIVATE_KEY` found (+0), and not OpenClaw (+15 skip, give points) score = 35 + 30 + 0 + 15 = **80**.
666
709
 
667
710
  #### Dimension 4: Runtime Protection (weight: 15%)
668
711
 
669
- Checks whether the agent has active security monitoring.
712
+ Checks whether the agent has active security monitoring. Start at **0**, add points for each check that **passes** (total possible = 100):
670
713
 
671
- | Check | Score | If failed → finding |
672
- |-------|-------|---------------------|
673
- | Security hooks/guards installed (AgentGuard, custom hooks, etc.) | +40 | "No security hooks installed — actions are unmonitored" (HIGH) |
674
- | Security audit log exists with recent events | +30 | "No security audit log — no threat history available" (MEDIUM) |
675
- | Skills have been security-scanned at least once | +30 | "Installed skills have never been security-scanned" (MEDIUM) |
714
+ | Check | Points if PASS | If FAIL → finding |
715
+ |-------|---------------|-------------------|
716
+ | Security hooks/guards installed (AgentGuard, custom hooks, etc.) | **+40** | "No security hooks installed — actions are unmonitored" (HIGH) |
717
+ | Security audit log exists with recent events | **+30** | "No security audit log — no threat history available" (MEDIUM) |
718
+ | Skills have been security-scanned at least once | **+30** | "Installed skills have never been security-scanned" (MEDIUM) |
676
719
 
677
720
  #### Dimension 5: Web3 Safety (weight: 15% if applicable)
678
721
 
679
- Only if Web3 usage is detected (env vars like `GOPLUS_API_KEY`, `CHAIN_ID`, `RPC_URL`, or web3-related skills installed). Otherwise `{ "score": null, "na": true }`.
722
+ Only if Web3 usage is detected (env vars like `GOPLUS_API_KEY`, `CHAIN_ID`, `RPC_URL`, or web3-related skills installed). Otherwise `{ "score": null, "na": true }`. Start at **0**, add points for each check that **passes** (total possible = 100):
723
+
724
+ | Check | Points if PASS | If FAIL → finding |
725
+ |-------|---------------|-------------------|
726
+ | No wallet-draining patterns (approve+transferFrom) in skill code | **+40** | "Wallet-draining pattern detected in <skill>" (CRITICAL) |
727
+ | No unlimited token approval patterns in skill code | **+30** | "Unlimited approval pattern detected in <skill>" (HIGH) |
728
+ | Transaction security API configured (GoPlus or equivalent) | **+30** | "No transaction security API — Web3 calls are unverified" (MEDIUM) |
729
+
730
+ #### Composite Score Calculation
731
+
732
+ Calculate the weighted average of all applicable dimensions:
733
+
734
+ ```
735
+ composite_score = (code_safety × 0.25) + (credential_safety × 0.25) + (network_exposure × 0.20) + (runtime_protection × 0.15) + (web3_safety × 0.15)
736
+ ```
737
+
738
+ If Web3 Safety is N/A, redistribute its 15% weight proportionally across the other 4 dimensions:
739
+ ```
740
+ composite_score = (code_safety × 0.294) + (credential_safety × 0.294) + (network_exposure × 0.235) + (runtime_protection × 0.176)
741
+ ```
680
742
 
681
- | Check | Score | If failed → finding |
682
- |-------|-------|---------------------|
683
- | No wallet-draining patterns (approve+transferFrom) in skill code | +40 | "Wallet-draining pattern detected in <skill>" (CRITICAL) |
684
- | No unlimited token approval patterns in skill code | +30 | "Unlimited approval pattern detected in <skill>" (HIGH) |
685
- | Transaction security API configured (GoPlus or equivalent) | +30 | "No transaction security API — Web3 calls are unverified" (MEDIUM) |
743
+ Round to the nearest integer.
686
744
 
687
- #### Composite Score
745
+ **Tier assignment (MUST use these exact thresholds):**
688
746
 
689
- Weighted average of all applicable dimensions. If Web3 Safety is N/A, redistribute its 15% weight proportionally.
747
+ | Score Range | Tier | Label |
748
+ |-------------|------|-------|
749
+ | **90–100** | **S** | JACKED |
750
+ | **70–89** | **A** | Healthy |
751
+ | **50–69** | **B** | Tired |
752
+ | **0–49** | **F** | Critical |
690
753
 
691
- Determine tier:
692
- - 90–100 → Tier **S** (JACKED)
693
- - 70–89 → Tier **A** (Healthy)
694
- - 50–69 → Tier **B** (Tired)
695
- - 0–49 → Tier **F** (Critical)
754
+ **Example**: code_safety=100, credential_safety=80, network_exposure=85, runtime_protection=30, web3=N/A → composite = (100×0.294)+(80×0.294)+(85×0.235)+(30×0.176) = 29.4+23.5+20.0+5.3 = **78** → Tier **A** (Healthy).
696
755
 
697
756
  ### Step 3: Generate Analysis Report
698
757
 
@@ -709,6 +768,18 @@ This report goes into the `"analysis"` field of the JSON output.
709
768
 
710
769
  Also generate a list of actionable recommendations as `{ "severity": "...", "text": "..." }` objects for the structured view.
711
770
 
771
+ ### Pre-Step-4 Validation
772
+
773
+ **Before assembling the JSON, verify you have collected data for ALL 5 dimensions:**
774
+
775
+ - [ ] `code_safety` — from Step 1 check 1 (skill scanning)
776
+ - [ ] `credential_safety` — from Step 1 checks 2 + 3 (permissions + DLP)
777
+ - [ ] `network_exposure` — from Step 1 checks 4 + 5 + 6 (ports + cron + env vars)
778
+ - [ ] `runtime_protection` — from Step 1 check 7 (hooks + audit log)
779
+ - [ ] `web3_safety` — from Step 2 (only if Web3 detected, otherwise `{ "score": null, "na": true }`)
780
+
781
+ **If any dimension is missing data, go back and run the missing checks. Do NOT submit a report with only code_safety filled in.**
782
+
712
783
  ### Step 4: Generate Report
713
784
 
714
785
  Assemble the results into a JSON object and pipe it to the report generator:
@@ -734,16 +805,21 @@ Assemble the results into a JSON object and pipe it to the report generator:
734
805
  }
735
806
  ```
736
807
 
737
- Execute (remember to `cd` into the skill directory first see "Resolving Script Paths" above):
808
+ Execute the report generator. **Use the `--file` method for cross-platform compatibility** (the `echo | pipe` method fails on Windows due to shell quoting differences):
809
+
810
+ 1. First, write the JSON to a temporary file using the Write tool (e.g. `/tmp/agentguard-checkup-data.json`)
811
+ 2. Then run (remember to `cd` into the skill directory first — see "Resolving Script Paths" above):
738
812
  ```bash
739
- cd <skill_directory> && echo '<json>' | node scripts/checkup-report.js
813
+ cd <skill_directory> && node scripts/checkup-report.js --file /tmp/agentguard-checkup-data.json
740
814
  ```
741
815
 
742
816
  The script outputs the HTML file path to stdout (e.g. `/tmp/agentguard-checkup-1234567890.html`). Capture this path — you will need it for delivery in Step 6.
743
817
 
744
- ### Step 5: Terminal Summary
818
+ > **Note**: The script also supports stdin pipe (`echo '<json>' | node scripts/checkup-report.js`) but this may fail on Windows cmd.exe where single quotes are not string delimiters. Always prefer `--file`.
819
+
820
+ ### Step 5: Terminal Summary (REQUIRED)
745
821
 
746
- After the report generates, output a brief summary in the terminal:
822
+ **You MUST output this summary after the report generates.** This is the primary output the user sees. Do NOT skip this step — always show the score, dimension table, and report path:
747
823
 
748
824
  ```
749
825
  ## 🦞 GoPlus AgentGuard Health Checkup
@@ -763,7 +839,27 @@ After the report generates, output a brief summary in the terminal:
763
839
  **Full visual report**: <path> (opened in browser)
764
840
 
765
841
  💡 Top recommendation: <first recommendation text>
842
+
843
+ ### Next Steps
844
+ (Only include this section if there are HIGH or CRITICAL findings.)
845
+
846
+ List each HIGH or CRITICAL finding as a plain-language suggestion — no commands, no JSON, no technical details. One sentence per item. Ask the user to confirm if they'd like help with any of them.
847
+
848
+ Format:
766
849
  ```
850
+ ⚠️ A few things need your attention:
851
+ 1. 🔴 <plain description of critical issue and why it matters>
852
+ 2. 🟠 <plain description of high issue and why it matters>
853
+ ...
854
+
855
+ Reply with the number(s) you'd like help with and I'll walk you through it.
856
+ ```
857
+
858
+ Examples of plain-language descriptions:
859
+ - No hooks: "Security monitoring isn't active — AgentGuard can't block threats in real-time until hooks are configured."
860
+ - Unregistered skills: "10 installed skills haven't been security-reviewed — they're running with no trust level assigned."
861
+ - SSH permissions: "Your SSH key folder has loose permissions — other processes on this machine could potentially read your private keys."
862
+ - Plaintext credential: "A private key or API token was found in plain text in a file — it should be removed and rotated."
767
863
 
768
864
  ### Step 6: Deliver the Report to the User
769
865
 
@@ -2,6 +2,7 @@
2
2
  "private": true,
3
3
  "type": "module",
4
4
  "dependencies": {
5
- "@goplus/agentguard": "^1.0.6"
5
+ "@goplus/agentguard": "^1.0.6",
6
+ "open": "11.0.0"
6
7
  }
7
8
  }