@upx-us/shield 0.7.0 → 0.7.1
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 +10 -0
- package/dist/src/cli-cases.js +34 -5
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/skills/shield/SKILL.md +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.7.1] — 2026-03-13
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
- Case ownership awareness: `shield cases` now shows which cases belong to this instance vs other instances in the org
|
|
11
|
+
- `--mine` flag for `shield cases` and `shield cases list` to filter to locally-owned cases
|
|
12
|
+
- Sibling case detail view: `shield cases show <ID>` notes when a case belongs to another org instance and clarifies that remote investigation requires direct platform access
|
|
13
|
+
- Attribution summary line when listing mixed-ownership cases
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
7
17
|
## [0.7.0] — 2026-03-13
|
|
8
18
|
|
|
9
19
|
### Added
|
package/dist/src/cli-cases.js
CHANGED
|
@@ -48,7 +48,7 @@ function registerCasesCli(shieldCommand) {
|
|
|
48
48
|
const cases = shieldCommand.command('cases')
|
|
49
49
|
.description('List and manage Shield security cases');
|
|
50
50
|
cases.action(async () => {
|
|
51
|
-
await listCases({ status: 'open', limit: '20', format: 'table' });
|
|
51
|
+
await listCases({ status: 'open', limit: '20', format: 'table', mine: false });
|
|
52
52
|
});
|
|
53
53
|
cases
|
|
54
54
|
.command('list')
|
|
@@ -56,6 +56,7 @@ function registerCasesCli(shieldCommand) {
|
|
|
56
56
|
.option('--status <status>', 'Filter: open, resolved, all', 'open')
|
|
57
57
|
.option('--limit <n>', 'Max results', '20')
|
|
58
58
|
.option('--format <fmt>', 'Output format: table or json', 'table')
|
|
59
|
+
.option('--mine', 'Show only cases from this instance')
|
|
59
60
|
.action(listCases);
|
|
60
61
|
cases
|
|
61
62
|
.command('show')
|
|
@@ -108,15 +109,37 @@ async function listCases(opts) {
|
|
|
108
109
|
console.log(JSON.stringify(result, null, 2));
|
|
109
110
|
return;
|
|
110
111
|
}
|
|
111
|
-
|
|
112
|
+
const own = result.cases.filter((c) => c.ownership === 'own').length;
|
|
113
|
+
const sibling = result.cases.filter((c) => c.ownership === 'sibling').length;
|
|
114
|
+
const unknown = result.cases.filter((c) => c.ownership === 'unknown' || c.ownership == null).length;
|
|
115
|
+
const visible = opts.mine
|
|
116
|
+
? result.cases.filter((c) => c.is_mine === true)
|
|
117
|
+
: result.cases;
|
|
118
|
+
if (visible.length === 0 && opts.mine && result.cases.length > 0) {
|
|
119
|
+
console.log('No cases attributed to this instance. Other org instances have open cases \u2014 run without --mine to see them.');
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (visible.length === 0) {
|
|
112
123
|
console.log('No open cases. \u2705');
|
|
113
124
|
return;
|
|
114
125
|
}
|
|
115
|
-
|
|
116
|
-
|
|
126
|
+
if (sibling > 0 || (own > 0 && unknown > 0)) {
|
|
127
|
+
const parts = [];
|
|
128
|
+
if (own > 0)
|
|
129
|
+
parts.push(`${own} from this instance`);
|
|
130
|
+
if (sibling > 0)
|
|
131
|
+
parts.push(`${sibling} from other instances`);
|
|
132
|
+
if (unknown > 0)
|
|
133
|
+
parts.push(`${unknown} unattributed`);
|
|
134
|
+
console.log(`Attribution: ${parts.join(', ')} (use --mine to filter)\n`);
|
|
135
|
+
}
|
|
136
|
+
console.log(`Cases (${visible.length} of ${result.total}):\n`);
|
|
137
|
+
for (const c of visible) {
|
|
117
138
|
const sev = (c.severity || '').padEnd(8);
|
|
118
139
|
const time = new Date(c.created_at).toLocaleString();
|
|
119
|
-
|
|
140
|
+
const ownershipTag = c.ownership === 'own' ? ' [mine]' :
|
|
141
|
+
c.ownership === 'sibling' ? ' [sibling]' : '';
|
|
142
|
+
console.log(` [${sev}]${ownershipTag} ${c.id}`);
|
|
120
143
|
console.log(` ${c.rule_title || c.rule_id}`);
|
|
121
144
|
console.log(` ${c.summary || ''}`);
|
|
122
145
|
console.log(` Created: ${time} Events: ${c.event_count || 0}\n`);
|
|
@@ -138,6 +161,12 @@ async function showCase(id, opts) {
|
|
|
138
161
|
}
|
|
139
162
|
console.log(`Case: ${result.id}`);
|
|
140
163
|
console.log(`Status: ${result.status} Severity: ${result.severity}`);
|
|
164
|
+
if (result.ownership === 'sibling') {
|
|
165
|
+
console.log(`Instance: sibling (belongs to another instance in your org \u2014 you can resolve it, but local log access is unavailable)`);
|
|
166
|
+
}
|
|
167
|
+
else if (result.ownership === 'own') {
|
|
168
|
+
console.log(`Instance: this instance`);
|
|
169
|
+
}
|
|
141
170
|
console.log(`Rule: ${result.rule_title || result.rule_id}`);
|
|
142
171
|
console.log(`Summary: ${result.summary || '\u2014'}`);
|
|
143
172
|
console.log(`Created: ${new Date(result.created_at).toLocaleString()}`);
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/skills/shield/SKILL.md
CHANGED
|
@@ -31,6 +31,8 @@ Shield requires the `@upx-us/shield` plugin and an active subscription.
|
|
|
31
31
|
| `openclaw shield logs --format json` | JSON output |
|
|
32
32
|
| `openclaw shield vault show` | Agent and workspace inventory, redaction summary (hashed IDs) |
|
|
33
33
|
| `openclaw shield cases` | List open security cases |
|
|
34
|
+
| `openclaw shield cases --mine` | List only cases from this instance |
|
|
35
|
+
| `openclaw shield cases list --mine` | Show only cases from this instance |
|
|
34
36
|
| `openclaw shield cases show <ID>` | Full case detail with events, rule, playbook |
|
|
35
37
|
| `openclaw shield cases resolve <ID>` | Resolve a case (--resolution, --root-cause, --comment) |
|
|
36
38
|
| `openclaw shield monitor` | Case notification cron — status, --on, --off, --interval |
|
|
@@ -78,6 +80,8 @@ Proceed normally. No onboarding message needed.
|
|
|
78
80
|
|
|
79
81
|
When a Shield case fires or the user asks about an alert: use `openclaw shield cases` to list open cases and `openclaw shield cases --id <id>` for full detail (timeline, matched events, playbook). Severity guidance: **CRITICAL/HIGH** → surface immediately and ask if they want to investigate; **MEDIUM** → present and offer a playbook walkthrough; **LOW/INFO** → mention without interrupting the current task. Always include: rule name, what it detects, when it fired, and the first recommended remediation step. Confirm with the user before resolving — never resolve autonomously.
|
|
80
82
|
|
|
83
|
+
When listing cases, note how many belong to this instance vs other org instances. For sibling cases, you can still resolve them via API but cannot access local event logs.
|
|
84
|
+
|
|
81
85
|
## Case Investigation Workflow
|
|
82
86
|
|
|
83
87
|
When a Shield case fires, correlate three data sources to determine true positive vs. false positive:
|