clawarmor 3.1.0 → 3.2.0
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/CHANGELOG.md +58 -0
- package/clawgear-skills/clawarmor-live-monitor/SKILL.md +120 -0
- package/clawgear-skills/hardened-operator-baseline/SKILL.md +172 -0
- package/clawgear-skills/incident-response-playbook/SKILL.md +189 -0
- package/clawgear-skills/skill-security-scanner/SKILL.md +170 -0
- package/cli.js +29 -3
- package/lib/audit-quiet.js +89 -0
- package/lib/baseline-cmd.js +189 -0
- package/lib/baseline.js +106 -0
- package/lib/incident-cmd.js +201 -0
- package/lib/scan.js +88 -17
- package/lib/skill-verify.js +259 -0
- package/package.json +1 -1
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [3.2.0] — 2026-03-03
|
|
4
|
+
|
|
5
|
+
### New Features
|
|
6
|
+
|
|
7
|
+
#### `clawarmor scan --json`
|
|
8
|
+
- Added `--json` flag to `clawarmor scan`
|
|
9
|
+
- Outputs a clean JSON object to stdout with: `verdict` (PASS/WARN/BLOCK), `score`, `totalSkills`, `flaggedSkills`, `findings[]`, `scannedAt`
|
|
10
|
+
- Verdict rules: BLOCK if any CRITICAL findings, WARN if any HIGH findings, PASS otherwise
|
|
11
|
+
- Designed for scripting and CI/CD integration (pipe to `jq`, parse in shell scripts)
|
|
12
|
+
|
|
13
|
+
#### `clawarmor baseline` command
|
|
14
|
+
- New command: `clawarmor baseline save [--name <label>]` — saves current audit result as a named baseline to `~/.openclaw/workspace/memory/clawarmor-baselines/`
|
|
15
|
+
- `clawarmor baseline list` — lists all saved baselines with date and score
|
|
16
|
+
- `clawarmor baseline diff [--from <label>] [--to <label>]` — diffs two baselines showing score delta, new findings, and resolved findings
|
|
17
|
+
- Enables tracking security posture over time and catching regressions after skill installs
|
|
18
|
+
|
|
19
|
+
#### `clawarmor incident` command
|
|
20
|
+
- New command: `clawarmor incident create --finding <description> --severity <CRITICAL|HIGH|MEDIUM> [--action <quarantine|rollback|notify>]`
|
|
21
|
+
- Creates a structured markdown incident log at `~/.openclaw/workspace/memory/incidents/YYYY-MM-DD-<slug>.md`
|
|
22
|
+
- `--action rollback` automatically triggers config rollback via existing snapshot system
|
|
23
|
+
- `clawarmor incident list` — lists all logged incidents with date and severity
|
|
24
|
+
|
|
25
|
+
#### `clawarmor skill verify <skill-dir>`
|
|
26
|
+
- New command that validates a skill directory against ClawGear publishing standards
|
|
27
|
+
- Checks: SKILL.md presence, no hardcoded credentials, no obfuscation, permissions declared if exec used, no fetches to unknown hosts, description in frontmatter
|
|
28
|
+
- Exit codes: 0=VERIFIED, 1=WARN, 2=BLOCK
|
|
29
|
+
- Human-readable output with emoji status per check
|
|
30
|
+
|
|
31
|
+
### ClawGear Security Skills
|
|
32
|
+
- Added 4 security skill SKILL.md files in `clawgear-skills/`:
|
|
33
|
+
- `clawarmor-live-monitor` — heartbeat monitoring with Telegram alerts on score drops
|
|
34
|
+
- `skill-security-scanner` — pre-install gate for skills using `scan --json`
|
|
35
|
+
- `hardened-operator-baseline` — 3-command full hardening sequence
|
|
36
|
+
- `incident-response-playbook` — automated incident response with rollback + alerting
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## [3.1.0] — 2026-02-XX
|
|
41
|
+
|
|
42
|
+
- Stack honesty fix + post-install audit + contextual profiles
|
|
43
|
+
|
|
44
|
+
## [3.0.1] — 2026-02-XX
|
|
45
|
+
|
|
46
|
+
- README rewrite — control plane positioning, stack orchestration docs
|
|
47
|
+
|
|
48
|
+
## [3.0.0] — 2026-02-XX
|
|
49
|
+
|
|
50
|
+
- Stack orchestrator — Invariant + IronCurtain integration
|
|
51
|
+
|
|
52
|
+
## [2.2.1] — 2026-01-XX
|
|
53
|
+
|
|
54
|
+
- Fix npm bloat (6.2MB→273KB), clean up README with v2.2 features
|
|
55
|
+
|
|
56
|
+
## [2.2.0] — 2026-01-XX
|
|
57
|
+
|
|
58
|
+
- Config snapshots + rollback, monitor mode for harden
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clawarmor-live-monitor
|
|
3
|
+
description: Monitors your OpenClaw agent security posture on every heartbeat. Diffs against a saved baseline and sends a Telegram alert if your score drops (e.g., after installing a new skill). Uses clawarmor baseline diff under the hood.
|
|
4
|
+
category: security
|
|
5
|
+
tags: [security, monitoring, heartbeat, clawarmor]
|
|
6
|
+
requires: clawarmor >= 3.2.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# clawarmor-live-monitor
|
|
10
|
+
|
|
11
|
+
Monitors your OpenClaw agent's security posture on every heartbeat cycle. After a new skill is installed, your score can silently drop — this skill catches that and alerts you before it becomes a problem.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
On every heartbeat, this skill:
|
|
16
|
+
1. Saves the current security posture as a `current` baseline
|
|
17
|
+
2. Diffs it against the saved `initial` baseline
|
|
18
|
+
3. If the score dropped by more than 5 points, fires a Telegram alert via `openclaw system event`
|
|
19
|
+
|
|
20
|
+
It uses `clawarmor baseline diff` under the hood — no custom scoring logic, just wiring.
|
|
21
|
+
|
|
22
|
+
## Why it matters
|
|
23
|
+
|
|
24
|
+
You install a skill, it looks fine. But it quietly adds an exec call or an outbound network fetch that ClawArmor would flag. Without continuous monitoring, you'd never know until the next manual audit. This skill closes that gap.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## Scripts
|
|
29
|
+
|
|
30
|
+
### `baseline-init.sh`
|
|
31
|
+
|
|
32
|
+
Run this once on first install to save your initial baseline.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
#!/usr/bin/env bash
|
|
36
|
+
# baseline-init.sh — save initial security baseline
|
|
37
|
+
set -e
|
|
38
|
+
|
|
39
|
+
echo "[clawarmor-live-monitor] Saving initial baseline..."
|
|
40
|
+
clawarmor baseline save --name initial
|
|
41
|
+
echo "[clawarmor-live-monitor] Initial baseline saved."
|
|
42
|
+
echo "Now paste heartbeat-fragment.md into your HEARTBEAT.md to enable continuous monitoring."
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### `monitor.sh`
|
|
46
|
+
|
|
47
|
+
Run on every heartbeat to check for score regressions.
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
#!/usr/bin/env bash
|
|
51
|
+
# monitor.sh — diff current posture against initial baseline
|
|
52
|
+
set -e
|
|
53
|
+
|
|
54
|
+
SKILL_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
55
|
+
|
|
56
|
+
# Save current posture
|
|
57
|
+
clawarmor baseline save --name current
|
|
58
|
+
|
|
59
|
+
# Diff against initial
|
|
60
|
+
DIFF_OUTPUT=$(clawarmor baseline diff --from initial --to current 2>&1)
|
|
61
|
+
SCORE_DELTA=$(echo "$DIFF_OUTPUT" | grep -oP 'Delta:\s*\K[+-]?\d+' | head -1)
|
|
62
|
+
|
|
63
|
+
echo "[clawarmor-live-monitor] Score delta: ${SCORE_DELTA:-0}"
|
|
64
|
+
|
|
65
|
+
# Alert if score dropped more than 5 points
|
|
66
|
+
if [ -n "$SCORE_DELTA" ] && [ "$SCORE_DELTA" -lt -5 ]; then
|
|
67
|
+
openclaw system event \
|
|
68
|
+
--text "⚠️ ClawArmor score dropped ${SCORE_DELTA} points since initial baseline. Run: clawarmor audit" \
|
|
69
|
+
--mode now
|
|
70
|
+
echo "[clawarmor-live-monitor] Alert sent."
|
|
71
|
+
fi
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### `heartbeat-fragment.md`
|
|
75
|
+
|
|
76
|
+
Paste this snippet into your `HEARTBEAT.md` to enable automatic monitoring:
|
|
77
|
+
|
|
78
|
+
```markdown
|
|
79
|
+
## Security Monitor
|
|
80
|
+
|
|
81
|
+
Run bash monitor.sh from skills/clawarmor-live-monitor/ — if score dropped, alert Alberto.
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Setup
|
|
87
|
+
|
|
88
|
+
1. **Install ClawArmor 3.2.0+**: `npm install -g clawarmor`
|
|
89
|
+
2. **Save your initial baseline** (run once):
|
|
90
|
+
```bash
|
|
91
|
+
bash ~/.openclaw/workspace/skills/clawarmor-live-monitor/baseline-init.sh
|
|
92
|
+
```
|
|
93
|
+
3. **Enable heartbeat monitoring** — paste the contents of `heartbeat-fragment.md` into your `HEARTBEAT.md`
|
|
94
|
+
|
|
95
|
+
That's it. On every heartbeat, your score will be checked against the initial baseline.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Manual usage
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
# Check current posture vs initial baseline
|
|
103
|
+
bash ~/.openclaw/workspace/skills/clawarmor-live-monitor/monitor.sh
|
|
104
|
+
|
|
105
|
+
# See all saved baselines
|
|
106
|
+
clawarmor baseline list
|
|
107
|
+
|
|
108
|
+
# Detailed diff
|
|
109
|
+
clawarmor baseline diff --from initial --to current
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Notes
|
|
115
|
+
|
|
116
|
+
- Requires clawarmor 3.2.0+ for the `baseline` commands
|
|
117
|
+
- The `current` baseline is overwritten on every heartbeat — it tracks the most recent posture only
|
|
118
|
+
- The `initial` baseline persists until you re-run `baseline-init.sh`
|
|
119
|
+
- Alert threshold is hardcoded at -5 points; edit `monitor.sh` to adjust
|
|
120
|
+
- Telegram delivery requires `openclaw system event` to be configured with a Telegram channel
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: hardened-operator-baseline
|
|
3
|
+
description: Full ClawArmor hardening in 3 commands. Detects your operator role (coding/browsing/messaging), applies contextual hardening, deploys Invariant + IronCurtain stack, saves a security baseline, and writes a SECURITY_RUNBOOK.md to your workspace. One-time setup for production-grade security posture.
|
|
4
|
+
category: security
|
|
5
|
+
tags: [security, hardening, baseline, clawarmor, invariant, ironcurtain]
|
|
6
|
+
requires: clawarmor >= 3.2.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# hardened-operator-baseline
|
|
10
|
+
|
|
11
|
+
Production-grade security hardening in 3 commands. Run this once to go from default OpenClaw config to a hardened, monitored, documented security posture.
|
|
12
|
+
|
|
13
|
+
## What it does
|
|
14
|
+
|
|
15
|
+
1. **Detects your operator role** (`clawarmor profile detect`) — coding, browsing, or messaging
|
|
16
|
+
2. **Applies contextual hardening** (`clawarmor harden --profile <detected>`) — tightens the settings that matter for your role without breaking your workflow
|
|
17
|
+
3. **Deploys the security stack and saves a baseline** (`clawarmor stack deploy && clawarmor baseline save --name post-harden`) — Invariant flow guardrails + IronCurtain instruction boundaries + a snapshot of your hardened posture
|
|
18
|
+
|
|
19
|
+
After running, a `SECURITY_RUNBOOK.md` is written to your workspace documenting what was done and how to respond to incidents.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## The 3 commands
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Step 1: Detect your operator role
|
|
27
|
+
clawarmor profile detect
|
|
28
|
+
|
|
29
|
+
# Step 2: Apply contextual hardening (replace <profile> with detected value)
|
|
30
|
+
clawarmor harden --profile <profile>
|
|
31
|
+
|
|
32
|
+
# Step 3: Deploy security stack and save baseline
|
|
33
|
+
clawarmor stack deploy && clawarmor baseline save --name post-harden
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Script
|
|
39
|
+
|
|
40
|
+
### `setup.sh`
|
|
41
|
+
|
|
42
|
+
Runs all 3 steps in sequence and writes `SECURITY_RUNBOOK.md` to your workspace.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
#!/usr/bin/env bash
|
|
46
|
+
# setup.sh — full ClawArmor hardening sequence
|
|
47
|
+
# Run once to set up production-grade security posture
|
|
48
|
+
|
|
49
|
+
set -e
|
|
50
|
+
|
|
51
|
+
WORKSPACE="$HOME/.openclaw/workspace"
|
|
52
|
+
RUNBOOK="$WORKSPACE/SECURITY_RUNBOOK.md"
|
|
53
|
+
|
|
54
|
+
echo ""
|
|
55
|
+
echo "=== ClawArmor Hardened Operator Baseline ==="
|
|
56
|
+
echo ""
|
|
57
|
+
|
|
58
|
+
# Step 1: Detect profile
|
|
59
|
+
echo "[1/3] Detecting operator profile..."
|
|
60
|
+
PROFILE=$(clawarmor profile detect 2>/dev/null | grep -oP 'Detected:\s*\K\w+' | head -1)
|
|
61
|
+
if [ -z "$PROFILE" ]; then
|
|
62
|
+
PROFILE="general"
|
|
63
|
+
echo " Profile detection failed — using 'general'"
|
|
64
|
+
else
|
|
65
|
+
echo " Detected profile: $PROFILE"
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Step 2: Apply hardening
|
|
69
|
+
echo ""
|
|
70
|
+
echo "[2/3] Applying contextual hardening (profile: $PROFILE)..."
|
|
71
|
+
clawarmor harden --profile "$PROFILE" --auto
|
|
72
|
+
echo " Hardening applied."
|
|
73
|
+
|
|
74
|
+
# Step 3: Deploy stack and save baseline
|
|
75
|
+
echo ""
|
|
76
|
+
echo "[3/3] Deploying security stack and saving baseline..."
|
|
77
|
+
clawarmor stack deploy
|
|
78
|
+
clawarmor baseline save --name post-harden
|
|
79
|
+
SCORE=$(clawarmor baseline list 2>/dev/null | grep -A2 'post-harden' | grep -oP 'Score:\s*\K[\d]+' | head -1)
|
|
80
|
+
SCORE="${SCORE:-unknown}"
|
|
81
|
+
echo " Stack deployed. Baseline saved. Score: $SCORE/100"
|
|
82
|
+
|
|
83
|
+
# Write SECURITY_RUNBOOK.md
|
|
84
|
+
DATE=$(date +%Y-%m-%d)
|
|
85
|
+
mkdir -p "$WORKSPACE"
|
|
86
|
+
|
|
87
|
+
cat > "$RUNBOOK" << EOF
|
|
88
|
+
# Security Runbook
|
|
89
|
+
**Hardened:** $DATE
|
|
90
|
+
**Profile:** $PROFILE
|
|
91
|
+
**Score:** $SCORE/100
|
|
92
|
+
**Stack:** Invariant + IronCurtain
|
|
93
|
+
|
|
94
|
+
## What's Protected
|
|
95
|
+
- Config locked via clawarmor harden
|
|
96
|
+
- Runtime guardrails via Invariant
|
|
97
|
+
- Instruction boundaries via IronCurtain
|
|
98
|
+
|
|
99
|
+
## Incident Response
|
|
100
|
+
1. Run: clawarmor audit
|
|
101
|
+
2. Check: clawarmor incident list
|
|
102
|
+
3. If CRITICAL: clawarmor rollback && clawarmor incident create --finding "..." --severity CRITICAL
|
|
103
|
+
|
|
104
|
+
## Contacts
|
|
105
|
+
- ClawArmor docs: github.com/pinzasai/clawarmor
|
|
106
|
+
- ClawGear support: clawgear.io
|
|
107
|
+
EOF
|
|
108
|
+
|
|
109
|
+
echo ""
|
|
110
|
+
echo "=== Done ==="
|
|
111
|
+
echo ""
|
|
112
|
+
echo " SECURITY_RUNBOOK.md written to: $RUNBOOK"
|
|
113
|
+
echo " Baseline saved as: post-harden"
|
|
114
|
+
echo " Score: $SCORE/100"
|
|
115
|
+
echo ""
|
|
116
|
+
echo " Next steps:"
|
|
117
|
+
echo " - Review SECURITY_RUNBOOK.md"
|
|
118
|
+
echo " - Run 'clawarmor audit' anytime to check current posture"
|
|
119
|
+
echo " - Run 'clawarmor baseline diff --from post-harden --to <new>' to track changes"
|
|
120
|
+
echo ""
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## After running
|
|
126
|
+
|
|
127
|
+
Your workspace will contain:
|
|
128
|
+
- **`SECURITY_RUNBOOK.md`** — incident response procedures, what's protected, contacts
|
|
129
|
+
- **`post-harden` baseline** — snapshot of your hardened posture for future diffs
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Check posture after any config changes
|
|
133
|
+
clawarmor baseline save --name $(date +%Y-%m-%d) && \
|
|
134
|
+
clawarmor baseline diff --from post-harden --to $(date +%Y-%m-%d)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## SECURITY_RUNBOOK.md template
|
|
140
|
+
|
|
141
|
+
The script generates this file automatically. You can also create it manually:
|
|
142
|
+
|
|
143
|
+
```markdown
|
|
144
|
+
# Security Runbook
|
|
145
|
+
**Hardened:** <date>
|
|
146
|
+
**Profile:** <profile>
|
|
147
|
+
**Score:** <score>/100
|
|
148
|
+
**Stack:** Invariant + IronCurtain
|
|
149
|
+
|
|
150
|
+
## What's Protected
|
|
151
|
+
- Config locked via clawarmor harden
|
|
152
|
+
- Runtime guardrails via Invariant
|
|
153
|
+
- Instruction boundaries via IronCurtain
|
|
154
|
+
|
|
155
|
+
## Incident Response
|
|
156
|
+
1. Run: clawarmor audit
|
|
157
|
+
2. Check: clawarmor incident list
|
|
158
|
+
3. If CRITICAL: clawarmor rollback && clawarmor incident create --finding "..." --severity CRITICAL
|
|
159
|
+
|
|
160
|
+
## Contacts
|
|
161
|
+
- ClawArmor docs: github.com/pinzasai/clawarmor
|
|
162
|
+
- ClawGear support: clawgear.io
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Notes
|
|
168
|
+
|
|
169
|
+
- Run `clawarmor baseline save` after any significant config changes to keep your diff history meaningful
|
|
170
|
+
- The `--auto` flag on harden applies SAFE and CAUTION fixes without prompting — omit it if you want to review each fix interactively
|
|
171
|
+
- Stack deploy requires Invariant and IronCurtain to be available in your environment
|
|
172
|
+
- Requires clawarmor 3.2.0+ for baseline commands
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: incident-response-playbook
|
|
3
|
+
description: Automated incident response for OpenClaw agents. When clawarmor audit finds a CRITICAL or HIGH finding, this playbook quarantines the affected extension, rolls back config to the last known-good snapshot, creates a structured incident log, and sends a Telegram alert. The action layer on top of ClawArmor detection.
|
|
4
|
+
category: security
|
|
5
|
+
tags: [security, incident-response, clawarmor, automation]
|
|
6
|
+
requires: clawarmor >= 3.2.0
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# incident-response-playbook
|
|
10
|
+
|
|
11
|
+
ClawArmor detects security issues. This skill responds to them. Automatically.
|
|
12
|
+
|
|
13
|
+
When a CRITICAL finding is detected, the playbook:
|
|
14
|
+
1. **Quarantines** the affected extension
|
|
15
|
+
2. **Rolls back** config to the last known-good snapshot
|
|
16
|
+
3. **Creates a structured incident log** via `clawarmor incident create`
|
|
17
|
+
4. **Sends a Telegram alert** via `openclaw system event`
|
|
18
|
+
|
|
19
|
+
Designed to run from your HEARTBEAT.md so it fires automatically on every cycle.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Scripts
|
|
24
|
+
|
|
25
|
+
### `quarantine.sh`
|
|
26
|
+
|
|
27
|
+
Disables a named extension and restarts the gateway.
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
#!/usr/bin/env bash
|
|
31
|
+
# quarantine.sh — disable an extension immediately
|
|
32
|
+
# Usage: bash quarantine.sh <extension-name>
|
|
33
|
+
# requires: elevated
|
|
34
|
+
|
|
35
|
+
EXTENSION="$1"
|
|
36
|
+
|
|
37
|
+
if [ -z "$EXTENSION" ]; then
|
|
38
|
+
echo "Usage: bash quarantine.sh <extension-name>"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
echo "[quarantine] Disabling extension: $EXTENSION"
|
|
43
|
+
openclaw config set "extensions.${EXTENSION}.disabled" true
|
|
44
|
+
openclaw gateway restart
|
|
45
|
+
|
|
46
|
+
echo "[quarantine] Extension '$EXTENSION' quarantined. Gateway restarted."
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### `respond.sh`
|
|
50
|
+
|
|
51
|
+
Full automated incident response: rollback, incident log, Telegram alert.
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
#!/usr/bin/env bash
|
|
55
|
+
# respond.sh — full incident response for a security finding
|
|
56
|
+
# Usage: bash respond.sh "<finding-description>" <CRITICAL|HIGH|MEDIUM>
|
|
57
|
+
# requires: clawarmor >= 3.2.0, elevated
|
|
58
|
+
|
|
59
|
+
FINDING="$1"
|
|
60
|
+
SEVERITY="${2:-CRITICAL}"
|
|
61
|
+
|
|
62
|
+
if [ -z "$FINDING" ]; then
|
|
63
|
+
echo "Usage: bash respond.sh \"<finding-description>\" <CRITICAL|HIGH|MEDIUM>"
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
echo ""
|
|
68
|
+
echo "[respond] Incident Response Triggered"
|
|
69
|
+
echo "[respond] Finding: $FINDING"
|
|
70
|
+
echo "[respond] Severity: $SEVERITY"
|
|
71
|
+
echo ""
|
|
72
|
+
|
|
73
|
+
# Step 1: Rollback config
|
|
74
|
+
echo "[respond] Rolling back to last known-good snapshot..."
|
|
75
|
+
ROLLBACK_OUTPUT=$(clawarmor rollback 2>&1)
|
|
76
|
+
ROLLBACK_STATUS=$?
|
|
77
|
+
|
|
78
|
+
if [ $ROLLBACK_STATUS -ne 0 ]; then
|
|
79
|
+
echo "[respond] WARNING: Rollback failed or no snapshots available."
|
|
80
|
+
echo "[respond] Operator must review config manually."
|
|
81
|
+
ROLLBACK_NOTE="Rollback failed — manual review required"
|
|
82
|
+
else
|
|
83
|
+
echo "[respond] Config rolled back."
|
|
84
|
+
ROLLBACK_NOTE="Config rolled back via clawarmor rollback"
|
|
85
|
+
fi
|
|
86
|
+
|
|
87
|
+
# Step 2: Create incident log
|
|
88
|
+
echo "[respond] Creating incident log..."
|
|
89
|
+
INCIDENT_FILE=$(clawarmor incident create \
|
|
90
|
+
--finding "$FINDING" \
|
|
91
|
+
--severity "$SEVERITY" \
|
|
92
|
+
--action rollback \
|
|
93
|
+
2>&1 | grep "File:" | awk '{print $2}')
|
|
94
|
+
echo "[respond] Incident logged: ${INCIDENT_FILE:-unknown}"
|
|
95
|
+
|
|
96
|
+
# Step 3: Send Telegram alert
|
|
97
|
+
echo "[respond] Sending alert..."
|
|
98
|
+
openclaw system event \
|
|
99
|
+
--text "🚨 Security Incident: $FINDING (Severity: $SEVERITY) — Config rolled back. Check: clawarmor incident list" \
|
|
100
|
+
--mode now
|
|
101
|
+
|
|
102
|
+
echo ""
|
|
103
|
+
echo "[respond] Done. Incident response complete."
|
|
104
|
+
echo ""
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### `check-and-respond.sh`
|
|
108
|
+
|
|
109
|
+
Runs `clawarmor audit --json`, finds CRITICAL findings, auto-triggers `respond.sh` for each.
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
#!/usr/bin/env bash
|
|
113
|
+
# check-and-respond.sh — auto-respond to new CRITICAL findings
|
|
114
|
+
# Add to HEARTBEAT.md to run automatically on every cycle
|
|
115
|
+
# requires: clawarmor >= 3.2.0, elevated
|
|
116
|
+
|
|
117
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
118
|
+
|
|
119
|
+
echo "[check-and-respond] Running security audit..."
|
|
120
|
+
AUDIT_JSON=$(clawarmor audit --json 2>/dev/null || echo '{"failed":[]}')
|
|
121
|
+
|
|
122
|
+
# Extract CRITICAL findings
|
|
123
|
+
CRITICALS=$(echo "$AUDIT_JSON" | python3 -c "
|
|
124
|
+
import sys, json
|
|
125
|
+
d = json.load(sys.stdin)
|
|
126
|
+
failed = d.get('failed', [])
|
|
127
|
+
for f in failed:
|
|
128
|
+
if f.get('severity') == 'CRITICAL' and not f.get('_profileExpected'):
|
|
129
|
+
print(f.get('title', f.get('id', 'Unknown finding')))
|
|
130
|
+
" 2>/dev/null)
|
|
131
|
+
|
|
132
|
+
if [ -z "$CRITICALS" ]; then
|
|
133
|
+
echo "[check-and-respond] No CRITICAL findings. Posture clean."
|
|
134
|
+
exit 0
|
|
135
|
+
fi
|
|
136
|
+
|
|
137
|
+
echo "[check-and-respond] CRITICAL findings detected — triggering response..."
|
|
138
|
+
echo ""
|
|
139
|
+
|
|
140
|
+
while IFS= read -r finding; do
|
|
141
|
+
if [ -n "$finding" ]; then
|
|
142
|
+
echo "[check-and-respond] Responding to: $finding"
|
|
143
|
+
bash "$SCRIPT_DIR/respond.sh" "$finding" "CRITICAL"
|
|
144
|
+
fi
|
|
145
|
+
done <<< "$CRITICALS"
|
|
146
|
+
|
|
147
|
+
echo "[check-and-respond] All findings processed."
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Heartbeat integration
|
|
153
|
+
|
|
154
|
+
Add this to your `HEARTBEAT.md` to auto-respond to new CRITICAL findings on every cycle:
|
|
155
|
+
|
|
156
|
+
```markdown
|
|
157
|
+
## Security Incident Response
|
|
158
|
+
|
|
159
|
+
Run bash check-and-respond.sh from skills/incident-response-playbook/ — automatically respond to any CRITICAL security findings found during audit.
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Manual usage
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
# Respond to a specific finding manually
|
|
168
|
+
bash ~/.openclaw/workspace/skills/incident-response-playbook/respond.sh \
|
|
169
|
+
"Malicious skill detected: bad-skill-v2" \
|
|
170
|
+
CRITICAL
|
|
171
|
+
|
|
172
|
+
# Quarantine a specific extension
|
|
173
|
+
bash ~/.openclaw/workspace/skills/incident-response-playbook/quarantine.sh \
|
|
174
|
+
bad-extension-name
|
|
175
|
+
|
|
176
|
+
# Run audit and auto-respond to everything critical
|
|
177
|
+
bash ~/.openclaw/workspace/skills/incident-response-playbook/check-and-respond.sh
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## Notes
|
|
183
|
+
|
|
184
|
+
- **Rollback** uses ClawArmor's snapshot system (`clawarmor rollback`). If no snapshot exists (e.g., hardening was never run), rollback is skipped and the operator is alerted to review manually
|
|
185
|
+
- **Quarantine** requires `openclaw config set` and `openclaw gateway restart` to be available — these are standard OpenClaw commands
|
|
186
|
+
- **Telegram delivery** requires `openclaw system event` to be configured with a Telegram channel
|
|
187
|
+
- The `--action rollback` flag on `clawarmor incident create` also triggers rollback automatically — `respond.sh` calls both for belt-and-suspenders reliability
|
|
188
|
+
- Requires clawarmor 3.2.0+ for `clawarmor incident` and `clawarmor audit --json`
|
|
189
|
+
- The scripts use `set -e` for fail-fast behavior — if any step errors, the script exits immediately. Check logs if a step is skipped unexpectedly
|