@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.
- package/README.md +33 -2
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +172 -0
- package/dist/cli.js.map +1 -0
- package/dist/cloud/client.d.ts +19 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +86 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/config.d.ts +31 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +131 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -1
- package/dist/index.js.map +1 -1
- package/dist/installers.d.ts +10 -0
- package/dist/installers.d.ts.map +1 -0
- package/dist/installers.js +137 -0
- package/dist/installers.js.map +1 -0
- package/dist/mcp-server.js +3 -2
- package/dist/mcp-server.js.map +1 -1
- package/dist/postinstall.d.ts +3 -0
- package/dist/postinstall.d.ts.map +1 -0
- package/dist/postinstall.js +13 -0
- package/dist/postinstall.js.map +1 -0
- package/dist/runtime/audit.d.ts +10 -0
- package/dist/runtime/audit.d.ts.map +1 -0
- package/dist/runtime/audit.js +94 -0
- package/dist/runtime/audit.js.map +1 -0
- package/dist/runtime/evaluator.d.ts +3 -0
- package/dist/runtime/evaluator.d.ts.map +1 -0
- package/dist/runtime/evaluator.js +197 -0
- package/dist/runtime/evaluator.js.map +1 -0
- package/dist/runtime/policy.d.ts +12 -0
- package/dist/runtime/policy.d.ts.map +1 -0
- package/dist/runtime/policy.js +81 -0
- package/dist/runtime/policy.js.map +1 -0
- package/dist/runtime/protect.d.ts +22 -0
- package/dist/runtime/protect.d.ts.map +1 -0
- package/dist/runtime/protect.js +172 -0
- package/dist/runtime/protect.js.map +1 -0
- package/dist/runtime/redaction.d.ts +6 -0
- package/dist/runtime/redaction.d.ts.map +1 -0
- package/dist/runtime/redaction.js +103 -0
- package/dist/runtime/redaction.js.map +1 -0
- package/dist/runtime/types.d.ts +62 -0
- package/dist/runtime/types.d.ts.map +1 -0
- package/dist/runtime/types.js +3 -0
- package/dist/runtime/types.js.map +1 -0
- package/dist/scanner/rules/trojan.js +1 -1
- package/dist/scanner/rules/trojan.js.map +1 -1
- package/dist/tests/cloud-live.test.d.ts +2 -0
- package/dist/tests/cloud-live.test.d.ts.map +1 -0
- package/dist/tests/cloud-live.test.js +68 -0
- package/dist/tests/cloud-live.test.js.map +1 -0
- package/dist/tests/installer.test.d.ts +2 -0
- package/dist/tests/installer.test.d.ts.map +1 -0
- package/dist/tests/installer.test.js +32 -0
- package/dist/tests/installer.test.js.map +1 -0
- package/dist/tests/runtime-cloud.test.d.ts +2 -0
- package/dist/tests/runtime-cloud.test.d.ts.map +1 -0
- package/dist/tests/runtime-cloud.test.js +202 -0
- package/dist/tests/runtime-cloud.test.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +7 -0
- package/dist/version.js.map +1 -0
- package/docs/SECURITY-POLICY.md +558 -0
- package/docs/architecture.md +54 -0
- package/docs/claude-code.md +41 -0
- package/docs/cloud-connect.md +73 -0
- package/docs/cloud-native-api.md +526 -0
- package/docs/codex.md +38 -0
- package/docs/goplus-api.md +38 -0
- package/docs/mcp-server.md +39 -0
- package/docs/openclaw.md +41 -0
- package/docs/privacy-boundary.md +37 -0
- package/docs/sdk.md +83 -0
- package/docs/trust-cli.md +58 -0
- package/examples/openclaw-docker/Dockerfile +10 -0
- package/examples/openclaw-docker/README.md +16 -0
- package/examples/openclaw-docker/docker-compose.yml +8 -0
- package/examples/openclaw-docker/plugin.ts +8 -0
- package/package.json +7 -2
- package/skills/agentguard/SKILL.md +157 -61
- package/skills/agentguard/{scripts/package.json → package.json} +2 -1
- package/skills/agentguard/patrol-checks.md +12 -2
- package/skills/agentguard/scan-rules.md +1 -1
- package/skills/agentguard/scripts/checkup-report.js +71 -30
package/docs/openclaw.md
ADDED
|
@@ -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
|
+
```
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@goplus/agentguard",
|
|
3
|
-
"version": "1.
|
|
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/
|
|
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
|
|
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 |
|
|
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/` (
|
|
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
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
-
|
|
619
|
-
-
|
|
620
|
-
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
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 check — behavior 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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 |
|
|
649
|
-
|
|
650
|
-
| `~/.ssh/` permissions are 700 or stricter |
|
|
651
|
-
| `~/.gnupg/` permissions are 700 or stricter |
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
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
|
-
|
|
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 |
|
|
672
|
-
|
|
673
|
-
| Security hooks/guards installed (AgentGuard, custom hooks, etc.) |
|
|
674
|
-
| Security audit log exists with recent events |
|
|
675
|
-
| Skills have been security-scanned at least once |
|
|
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
|
-
|
|
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
|
-
|
|
745
|
+
**Tier assignment (MUST use these exact thresholds):**
|
|
688
746
|
|
|
689
|
-
|
|
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
|
-
|
|
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
|
|
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> &&
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|