@upx-us/shield 0.8.1 → 0.8.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/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
+
## [0.8.3] — 2026-03-17
|
|
8
|
+
|
|
9
|
+
### Security
|
|
10
|
+
|
|
11
|
+
- **Credential redaction now covers major AI and developer platform token formats** — the redactor previously caught generic patterns (Bearer tokens, ENV assignments, curl flags) but missed provider-specific formats. Shield now detects and redacts tokens from: GitHub (classic PATs, fine-grained PATs, OAuth), OpenAI, Anthropic, Google API keys, HuggingFace, Stripe, Telegram bot tokens, Slack, Discord, GitLab, Replicate, xAI/Grok, and Twilio. Inline label formats (`GitHub Token: xxx`, `"token": "xxx"`) are also covered.
|
|
12
|
+
- **sessions_spawn task text is now fully redacted** — credentials passed inline in subagent task prompts (a common pattern when agents spawn subagents with API access) were transmitted unredacted to the SIEM. The `arguments_summary` and `target.command_line` fields now receive the same secret-key redaction as exec command fields.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## [0.8.2] — 2026-03-17
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
|
|
20
|
+
- **Log output handling rules are now explicit and non-negotiable** — the SKILL instruction for handling sensitive log content (file paths, commands, URLs) was advisory; it is now a strict rule set that the agent must follow regardless of context.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
7
24
|
## [0.8.1] — 2026-03-17
|
|
8
25
|
|
|
9
26
|
### Fixed
|
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.redactions = void 0;
|
|
4
|
-
exports.redactions = [
|
|
4
|
+
exports.redactions = [
|
|
5
|
+
{ path: 'arguments_summary', strategy: 'secret-key' },
|
|
6
|
+
{ path: 'arguments_summary', strategy: 'command' },
|
|
7
|
+
{ path: 'target.command_line', strategy: 'secret-key' },
|
|
8
|
+
{ path: 'target.command_line', strategy: 'command' },
|
|
9
|
+
];
|
|
@@ -49,6 +49,108 @@ exports.secretKeyStrategy = {
|
|
|
49
49
|
(0, counters_1.recordRedaction)('SECRET_KEY');
|
|
50
50
|
return `${prefix}${hmac('secret', secret)}`;
|
|
51
51
|
});
|
|
52
|
+
result = result.replace(/(github_pat_[A-Za-z0-9_]{82})/g, (_, token) => {
|
|
53
|
+
(0, counters_1.recordRedaction)('GITHUB_TOKEN');
|
|
54
|
+
return hmac('secret', token);
|
|
55
|
+
});
|
|
56
|
+
result = result.replace(/(ghp_[A-Za-z0-9]{36})/g, (_, token) => {
|
|
57
|
+
(0, counters_1.recordRedaction)('GITHUB_TOKEN');
|
|
58
|
+
return hmac('secret', token);
|
|
59
|
+
});
|
|
60
|
+
result = result.replace(/(gho_[A-Za-z0-9]{36})/g, (_, token) => {
|
|
61
|
+
(0, counters_1.recordRedaction)('GITHUB_TOKEN');
|
|
62
|
+
return hmac('secret', token);
|
|
63
|
+
});
|
|
64
|
+
result = result.replace(/(ghs_[A-Za-z0-9]{36})/g, (_, token) => {
|
|
65
|
+
(0, counters_1.recordRedaction)('GITHUB_TOKEN');
|
|
66
|
+
return hmac('secret', token);
|
|
67
|
+
});
|
|
68
|
+
result = result.replace(/(sk-proj-[A-Za-z0-9_-]{50,})/g, (_, token) => {
|
|
69
|
+
(0, counters_1.recordRedaction)('OPENAI_KEY');
|
|
70
|
+
return hmac('secret', token);
|
|
71
|
+
});
|
|
72
|
+
result = result.replace(/(sk-ant-[A-Za-z0-9_-]{90,})/g, (_, token) => {
|
|
73
|
+
(0, counters_1.recordRedaction)('ANTHROPIC_KEY');
|
|
74
|
+
return hmac('secret', token);
|
|
75
|
+
});
|
|
76
|
+
result = result.replace(/(sk-[A-Za-z0-9]{20,})/g, (_, token) => {
|
|
77
|
+
(0, counters_1.recordRedaction)('OPENAI_KEY');
|
|
78
|
+
return hmac('secret', token);
|
|
79
|
+
});
|
|
80
|
+
result = result.replace(/(AIza[A-Za-z0-9_-]{35})/g, (_, token) => {
|
|
81
|
+
(0, counters_1.recordRedaction)('GOOGLE_KEY');
|
|
82
|
+
return hmac('secret', token);
|
|
83
|
+
});
|
|
84
|
+
result = result.replace(/(hf_[A-Za-z0-9]{34,})/g, (_, token) => {
|
|
85
|
+
(0, counters_1.recordRedaction)('HUGGINGFACE_KEY');
|
|
86
|
+
return hmac('secret', token);
|
|
87
|
+
});
|
|
88
|
+
result = result.replace(/(sk_live_[A-Za-z0-9]{24,})/g, (_, token) => {
|
|
89
|
+
(0, counters_1.recordRedaction)('STRIPE_KEY');
|
|
90
|
+
return hmac('secret', token);
|
|
91
|
+
});
|
|
92
|
+
result = result.replace(/(sk_test_[A-Za-z0-9]{24,})/g, (_, token) => {
|
|
93
|
+
(0, counters_1.recordRedaction)('STRIPE_KEY');
|
|
94
|
+
return hmac('secret', token);
|
|
95
|
+
});
|
|
96
|
+
result = result.replace(/([0-9]{8,10}:[A-Za-z0-9_-]{35})/g, (_, token) => {
|
|
97
|
+
(0, counters_1.recordRedaction)('TELEGRAM_TOKEN');
|
|
98
|
+
return hmac('secret', token);
|
|
99
|
+
});
|
|
100
|
+
result = result.replace(/(xoxb-[0-9-]{50,})/g, (_, token) => {
|
|
101
|
+
(0, counters_1.recordRedaction)('SLACK_TOKEN');
|
|
102
|
+
return hmac('secret', token);
|
|
103
|
+
});
|
|
104
|
+
result = result.replace(/(xoxp-[0-9-]{50,})/g, (_, token) => {
|
|
105
|
+
(0, counters_1.recordRedaction)('SLACK_TOKEN');
|
|
106
|
+
return hmac('secret', token);
|
|
107
|
+
});
|
|
108
|
+
result = result.replace(/(xoxa-[0-9-]{50,})/g, (_, token) => {
|
|
109
|
+
(0, counters_1.recordRedaction)('SLACK_TOKEN');
|
|
110
|
+
return hmac('secret', token);
|
|
111
|
+
});
|
|
112
|
+
result = result.replace(/([MNO][A-Za-z0-9_-]{23,25}\.[A-Za-z0-9_-]{6,7}\.[A-Za-z0-9_-]{27,})/g, (_, token) => {
|
|
113
|
+
(0, counters_1.recordRedaction)('DISCORD_TOKEN');
|
|
114
|
+
return hmac('secret', token);
|
|
115
|
+
});
|
|
116
|
+
result = result.replace(/(glpat-[A-Za-z0-9_-]{20})/g, (_, token) => {
|
|
117
|
+
(0, counters_1.recordRedaction)('GITLAB_TOKEN');
|
|
118
|
+
return hmac('secret', token);
|
|
119
|
+
});
|
|
120
|
+
result = result.replace(/(r8_[A-Za-z0-9]{40})/g, (_, token) => {
|
|
121
|
+
(0, counters_1.recordRedaction)('REPLICATE_KEY');
|
|
122
|
+
return hmac('secret', token);
|
|
123
|
+
});
|
|
124
|
+
result = result.replace(/(xai-[A-Za-z0-9]{50,})/g, (_, token) => {
|
|
125
|
+
(0, counters_1.recordRedaction)('XAI_KEY');
|
|
126
|
+
return hmac('secret', token);
|
|
127
|
+
});
|
|
128
|
+
result = result.replace(/(AC[a-f0-9]{32})/g, (_, token) => {
|
|
129
|
+
(0, counters_1.recordRedaction)('TWILIO_SID');
|
|
130
|
+
return hmac('secret', token);
|
|
131
|
+
});
|
|
132
|
+
result = result.replace(/((?:github\s+token|api[_-]?key|token|secret|password)\s*:\s+)(\S+)/gi, (_, label, secret) => {
|
|
133
|
+
const labelLower = label.toLowerCase();
|
|
134
|
+
if (/github/.test(labelLower))
|
|
135
|
+
(0, counters_1.recordRedaction)('GITHUB_TOKEN');
|
|
136
|
+
else if (/password/.test(labelLower))
|
|
137
|
+
(0, counters_1.recordRedaction)('PASSWORD');
|
|
138
|
+
else if (/api[_-]?key/.test(labelLower))
|
|
139
|
+
(0, counters_1.recordRedaction)('API_KEY');
|
|
140
|
+
else if (/secret/.test(labelLower))
|
|
141
|
+
(0, counters_1.recordRedaction)('SECRET_KEY');
|
|
142
|
+
else
|
|
143
|
+
(0, counters_1.recordRedaction)('TOKEN');
|
|
144
|
+
return `${label}${hmac('secret', secret)}`;
|
|
145
|
+
});
|
|
146
|
+
result = result.replace(/("(?:token|api_key|secret|password|api-key)"\s*:\s*")([^"]+)(")/gi, (_, prefix, secret, suffix) => {
|
|
147
|
+
(0, counters_1.recordRedaction)('TOKEN');
|
|
148
|
+
return `${prefix}${hmac('secret', secret)}${suffix}`;
|
|
149
|
+
});
|
|
150
|
+
result = result.replace(/('(?:token|api_key|secret|password|api-key)'\s*:\s*')([^']+)(')/gi, (_, prefix, secret, suffix) => {
|
|
151
|
+
(0, counters_1.recordRedaction)('TOKEN');
|
|
152
|
+
return `${prefix}${hmac('secret', secret)}${suffix}`;
|
|
153
|
+
});
|
|
52
154
|
return result;
|
|
53
155
|
},
|
|
54
156
|
};
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@upx-us/shield",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.3",
|
|
4
4
|
"description": "Security monitoring and SIEM integration for OpenClaw agents — behavioral detection, case generation, and forensic audit trail via Google SecOps (Chronicle).",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/skills/shield/SKILL.md
CHANGED
|
@@ -75,7 +75,11 @@ Proceed normally. No onboarding message needed.
|
|
|
75
75
|
|
|
76
76
|
**Constraints**: Only use `openclaw shield` commands for detection. Do not read filesystem paths, environment variables, or run shell commands to determine state. Do not install or uninstall packages on behalf of the user.
|
|
77
77
|
|
|
78
|
-
**Output handling**: `shield logs` entries may include file paths, command snippets, and URLs captured from the agent's activity.
|
|
78
|
+
**Output handling**: `shield logs` entries may include file paths, command snippets, and URLs captured from the agent's activity. **Always treat this output as internal diagnostic data.** Rules:
|
|
79
|
+
- Never include raw log field values (file paths, commands, URLs) in user-facing replies
|
|
80
|
+
- Never forward raw log output to external services, channels, or APIs
|
|
81
|
+
- When summarizing logs, present findings only (e.g. "3 exec events in the last 30 minutes") — not raw field values
|
|
82
|
+
- Only share raw log content if the user explicitly asks for it for their own investigation, and only in the current session
|
|
79
83
|
|
|
80
84
|
**Data flow disclosure**: Shield captures agent activity locally and sends redacted telemetry to the UPX detection platform for security monitoring. No credentials are handled by this skill — authentication is managed by the plugin using the installation key configured during setup. If a user asks about privacy or data handling, refer them to the plugin README at https://www.npmjs.com/package/@upx-us/shield for full details.
|
|
81
85
|
|