@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
  };
@@ -2,7 +2,7 @@
2
2
  "id": "shield",
3
3
  "name": "OpenClaw Shield",
4
4
  "description": "Real-time security monitoring — streams enriched, redacted security events to the Shield detection platform.",
5
- "version": "0.8.1",
5
+ "version": "0.8.3",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@upx-us/shield",
3
- "version": "0.8.1",
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",
@@ -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. Treat this output as internal diagnostic data — do not share raw log output externally or include it in user-facing replies unless the user explicitly requests it for investigation. When summarizing logs, present findings rather than raw field values.
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