@upx-us/shield 0.2.12-beta
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.
Potentially problematic release.
This version of @upx-us/shield might be problematic. Click here for more details.
- package/LICENSE +38 -0
- package/README.md +96 -0
- package/dist/index.d.ts +43 -0
- package/dist/index.js +365 -0
- package/dist/src/config.d.ts +43 -0
- package/dist/src/config.js +181 -0
- package/dist/src/events/base.d.ts +110 -0
- package/dist/src/events/base.js +61 -0
- package/dist/src/events/browser/enrich.d.ts +3 -0
- package/dist/src/events/browser/enrich.js +46 -0
- package/dist/src/events/browser/event.d.ts +10 -0
- package/dist/src/events/browser/event.js +2 -0
- package/dist/src/events/browser/index.d.ts +4 -0
- package/dist/src/events/browser/index.js +13 -0
- package/dist/src/events/browser/redactions.d.ts +2 -0
- package/dist/src/events/browser/redactions.js +4 -0
- package/dist/src/events/browser/validations.d.ts +3 -0
- package/dist/src/events/browser/validations.js +10 -0
- package/dist/src/events/cron/enrich.d.ts +3 -0
- package/dist/src/events/cron/enrich.js +44 -0
- package/dist/src/events/cron/event.d.ts +5 -0
- package/dist/src/events/cron/event.js +2 -0
- package/dist/src/events/cron/index.d.ts +4 -0
- package/dist/src/events/cron/index.js +13 -0
- package/dist/src/events/cron/redactions.d.ts +2 -0
- package/dist/src/events/cron/redactions.js +4 -0
- package/dist/src/events/cron/validations.d.ts +3 -0
- package/dist/src/events/cron/validations.js +4 -0
- package/dist/src/events/exec/enrich.d.ts +3 -0
- package/dist/src/events/exec/enrich.js +80 -0
- package/dist/src/events/exec/event.d.ts +11 -0
- package/dist/src/events/exec/event.js +2 -0
- package/dist/src/events/exec/index.d.ts +4 -0
- package/dist/src/events/exec/index.js +13 -0
- package/dist/src/events/exec/redactions.d.ts +3 -0
- package/dist/src/events/exec/redactions.js +12 -0
- package/dist/src/events/exec/validations.d.ts +3 -0
- package/dist/src/events/exec/validations.js +12 -0
- package/dist/src/events/file/enrich.d.ts +3 -0
- package/dist/src/events/file/enrich.js +63 -0
- package/dist/src/events/file/event.d.ts +11 -0
- package/dist/src/events/file/event.js +2 -0
- package/dist/src/events/file/index.d.ts +4 -0
- package/dist/src/events/file/index.js +13 -0
- package/dist/src/events/file/redactions.d.ts +2 -0
- package/dist/src/events/file/redactions.js +8 -0
- package/dist/src/events/file/validations.d.ts +3 -0
- package/dist/src/events/file/validations.js +10 -0
- package/dist/src/events/gateway/enrich.d.ts +3 -0
- package/dist/src/events/gateway/enrich.js +50 -0
- package/dist/src/events/gateway/event.d.ts +5 -0
- package/dist/src/events/gateway/event.js +2 -0
- package/dist/src/events/gateway/index.d.ts +4 -0
- package/dist/src/events/gateway/index.js +13 -0
- package/dist/src/events/gateway/redactions.d.ts +2 -0
- package/dist/src/events/gateway/redactions.js +4 -0
- package/dist/src/events/gateway/validations.d.ts +3 -0
- package/dist/src/events/gateway/validations.js +4 -0
- package/dist/src/events/generic/enrich.d.ts +3 -0
- package/dist/src/events/generic/enrich.js +30 -0
- package/dist/src/events/generic/event.d.ts +5 -0
- package/dist/src/events/generic/event.js +2 -0
- package/dist/src/events/generic/index.d.ts +5 -0
- package/dist/src/events/generic/index.js +14 -0
- package/dist/src/events/generic/redactions.d.ts +2 -0
- package/dist/src/events/generic/redactions.js +4 -0
- package/dist/src/events/generic/validations.d.ts +3 -0
- package/dist/src/events/generic/validations.js +4 -0
- package/dist/src/events/host-telemetry/enrich.d.ts +3 -0
- package/dist/src/events/host-telemetry/enrich.js +28 -0
- package/dist/src/events/host-telemetry/event.d.ts +4 -0
- package/dist/src/events/host-telemetry/event.js +2 -0
- package/dist/src/events/host-telemetry/index.d.ts +4 -0
- package/dist/src/events/host-telemetry/index.js +13 -0
- package/dist/src/events/host-telemetry/redactions.d.ts +2 -0
- package/dist/src/events/host-telemetry/redactions.js +4 -0
- package/dist/src/events/host-telemetry/validations.d.ts +3 -0
- package/dist/src/events/host-telemetry/validations.js +4 -0
- package/dist/src/events/index.d.ts +40 -0
- package/dist/src/events/index.js +39 -0
- package/dist/src/events/message/enrich.d.ts +3 -0
- package/dist/src/events/message/enrich.js +36 -0
- package/dist/src/events/message/event.d.ts +5 -0
- package/dist/src/events/message/event.js +2 -0
- package/dist/src/events/message/index.d.ts +4 -0
- package/dist/src/events/message/index.js +13 -0
- package/dist/src/events/message/redactions.d.ts +2 -0
- package/dist/src/events/message/redactions.js +4 -0
- package/dist/src/events/message/validations.d.ts +3 -0
- package/dist/src/events/message/validations.js +7 -0
- package/dist/src/events/sessions-spawn/enrich.d.ts +3 -0
- package/dist/src/events/sessions-spawn/enrich.js +40 -0
- package/dist/src/events/sessions-spawn/event.d.ts +9 -0
- package/dist/src/events/sessions-spawn/event.js +2 -0
- package/dist/src/events/sessions-spawn/index.d.ts +4 -0
- package/dist/src/events/sessions-spawn/index.js +13 -0
- package/dist/src/events/sessions-spawn/redactions.d.ts +2 -0
- package/dist/src/events/sessions-spawn/redactions.js +4 -0
- package/dist/src/events/sessions-spawn/validations.d.ts +3 -0
- package/dist/src/events/sessions-spawn/validations.js +4 -0
- package/dist/src/events/tool-result/enrich.d.ts +13 -0
- package/dist/src/events/tool-result/enrich.js +46 -0
- package/dist/src/events/tool-result/event.d.ts +7 -0
- package/dist/src/events/tool-result/event.js +2 -0
- package/dist/src/events/tool-result/index.d.ts +4 -0
- package/dist/src/events/tool-result/index.js +9 -0
- package/dist/src/events/tool-result/redactions.d.ts +2 -0
- package/dist/src/events/tool-result/redactions.js +7 -0
- package/dist/src/events/tool-result/validations.d.ts +3 -0
- package/dist/src/events/tool-result/validations.js +9 -0
- package/dist/src/events/web/enrich.d.ts +8 -0
- package/dist/src/events/web/enrich.js +78 -0
- package/dist/src/events/web/event.d.ts +10 -0
- package/dist/src/events/web/event.js +2 -0
- package/dist/src/events/web/index.d.ts +4 -0
- package/dist/src/events/web/index.js +13 -0
- package/dist/src/events/web/redactions.d.ts +2 -0
- package/dist/src/events/web/redactions.js +6 -0
- package/dist/src/events/web/validations.d.ts +3 -0
- package/dist/src/events/web/validations.js +10 -0
- package/dist/src/fetcher.d.ts +12 -0
- package/dist/src/fetcher.js +182 -0
- package/dist/src/host-collector.d.ts +1 -0
- package/dist/src/host-collector.js +200 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.js +210 -0
- package/dist/src/log.d.ts +39 -0
- package/dist/src/log.js +102 -0
- package/dist/src/redactor/base.d.ts +29 -0
- package/dist/src/redactor/base.js +9 -0
- package/dist/src/redactor/index.d.ts +27 -0
- package/dist/src/redactor/index.js +109 -0
- package/dist/src/redactor/strategies/command.d.ts +2 -0
- package/dist/src/redactor/strategies/command.js +19 -0
- package/dist/src/redactor/strategies/hostname.d.ts +2 -0
- package/dist/src/redactor/strategies/hostname.js +15 -0
- package/dist/src/redactor/strategies/index.d.ts +13 -0
- package/dist/src/redactor/strategies/index.js +25 -0
- package/dist/src/redactor/strategies/path.d.ts +2 -0
- package/dist/src/redactor/strategies/path.js +23 -0
- package/dist/src/redactor/strategies/secret-key.d.ts +2 -0
- package/dist/src/redactor/strategies/secret-key.js +22 -0
- package/dist/src/redactor/strategies/username.d.ts +2 -0
- package/dist/src/redactor/strategies/username.js +12 -0
- package/dist/src/redactor/vault.d.ts +25 -0
- package/dist/src/redactor/vault.js +209 -0
- package/dist/src/sender.d.ts +29 -0
- package/dist/src/sender.js +186 -0
- package/dist/src/setup.d.ts +10 -0
- package/dist/src/setup.js +222 -0
- package/dist/src/transformer.d.ts +26 -0
- package/dist/src/transformer.js +302 -0
- package/dist/src/validator.d.ts +17 -0
- package/dist/src/validator.js +110 -0
- package/dist/src/version.d.ts +1 -0
- package/dist/src/version.js +19 -0
- package/openclaw.plugin.json +52 -0
- package/package.json +64 -0
- package/skills/shield/SKILL.md +38 -0
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* sender.ts ā Shield ingest API sender
|
|
4
|
+
*
|
|
5
|
+
* Posts events to the Shield ingest API via HMAC-SHA256 authentication.
|
|
6
|
+
* Events are batched and sent to the configured Shield endpoint only ā
|
|
7
|
+
* no cloud provider details are exposed in this module.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.REQUEST_TIMEOUT_MS = void 0;
|
|
44
|
+
exports._signRequestWithSecret = _signRequestWithSecret;
|
|
45
|
+
exports.sendEvents = sendEvents;
|
|
46
|
+
exports.reportInstance = reportInstance;
|
|
47
|
+
const crypto_1 = require("crypto");
|
|
48
|
+
const log = __importStar(require("./log"));
|
|
49
|
+
const version_1 = require("./version");
|
|
50
|
+
const BATCH_SIZE = 100;
|
|
51
|
+
exports.REQUEST_TIMEOUT_MS = 30_000;
|
|
52
|
+
function errMsg(err) {
|
|
53
|
+
return err instanceof Error ? err.message : String(err);
|
|
54
|
+
}
|
|
55
|
+
function envHeaders(shieldEnv) {
|
|
56
|
+
return shieldEnv ? { 'X-Shield-Env': shieldEnv } : {};
|
|
57
|
+
}
|
|
58
|
+
function generateNonce() {
|
|
59
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
60
|
+
}
|
|
61
|
+
function signRequest(instanceId, nonce, secret) {
|
|
62
|
+
const message = `${instanceId}:${nonce}`;
|
|
63
|
+
return (0, crypto_1.createHmac)('sha256', secret).update(message).digest('hex');
|
|
64
|
+
}
|
|
65
|
+
/** Exported for testing only ā computes HMAC with an explicit secret */
|
|
66
|
+
function _signRequestWithSecret(secret, instanceId, nonce) {
|
|
67
|
+
const message = `${instanceId}:${nonce}`;
|
|
68
|
+
return (0, crypto_1.createHmac)('sha256', secret).update(message).digest('hex');
|
|
69
|
+
}
|
|
70
|
+
async function fetchWithTimeout(url, init, timeoutMs = exports.REQUEST_TIMEOUT_MS) {
|
|
71
|
+
const controller = new AbortController();
|
|
72
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
73
|
+
try {
|
|
74
|
+
return await fetch(url, { ...init, signal: controller.signal });
|
|
75
|
+
}
|
|
76
|
+
finally {
|
|
77
|
+
clearTimeout(timer);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function sendEvents(events, config) {
|
|
81
|
+
if (events.length === 0)
|
|
82
|
+
return [];
|
|
83
|
+
if (config.dryRun) {
|
|
84
|
+
log.info('sender', `DRY RUN ā ${events.length} events in ${Math.ceil(events.length / BATCH_SIZE)} batch(es) (not sent)`);
|
|
85
|
+
for (let i = 0; i < events.length; i += BATCH_SIZE) {
|
|
86
|
+
const batch = events.slice(i, i + BATCH_SIZE);
|
|
87
|
+
const toolNames = batch.map((e) => e.event?.tool_name || 'unknown').join(', ');
|
|
88
|
+
log.info('sender', `Batch ${Math.floor(i / BATCH_SIZE) + 1}: ${batch.length} events [${toolNames}]`);
|
|
89
|
+
log.debug('sender', `Dry-run batch detail`, { entries: batch });
|
|
90
|
+
}
|
|
91
|
+
return [{ success: true, statusCode: 200, body: 'dry-run', eventCount: events.length }];
|
|
92
|
+
}
|
|
93
|
+
const { apiUrl, instanceId, hmacSecret, shieldEnv } = config.credentials;
|
|
94
|
+
if (!apiUrl || !instanceId || !hmacSecret) {
|
|
95
|
+
log.error('sender', 'Missing credentials (apiUrl, instanceId, or hmacSecret). Run: npx shield-setup');
|
|
96
|
+
return [{ success: false, statusCode: 0, body: 'missing credentials', eventCount: events.length }];
|
|
97
|
+
}
|
|
98
|
+
const results = [];
|
|
99
|
+
for (let i = 0; i < events.length; i += BATCH_SIZE) {
|
|
100
|
+
const batch = events.slice(i, i + BATCH_SIZE);
|
|
101
|
+
const batchNum = Math.floor(i / BATCH_SIZE) + 1;
|
|
102
|
+
const payload = JSON.stringify({ entries: batch });
|
|
103
|
+
const nonce = generateNonce();
|
|
104
|
+
const signature = signRequest(instanceId, nonce, hmacSecret);
|
|
105
|
+
log.debug('sender', `Batch ${batchNum}: ${batch.length} events ā ${apiUrl}/v1/ingest [env=${shieldEnv || 'dev'}]`);
|
|
106
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
107
|
+
try {
|
|
108
|
+
const res = await fetchWithTimeout(`${apiUrl}/v1/ingest`, {
|
|
109
|
+
method: 'POST',
|
|
110
|
+
headers: {
|
|
111
|
+
'Content-Type': 'application/json',
|
|
112
|
+
'X-Shield-Instance-Id': instanceId,
|
|
113
|
+
'X-Shield-Nonce': nonce,
|
|
114
|
+
'X-Shield-Signature': signature,
|
|
115
|
+
'X-Shield-Version': version_1.VERSION,
|
|
116
|
+
...envHeaders(shieldEnv),
|
|
117
|
+
},
|
|
118
|
+
body: payload,
|
|
119
|
+
});
|
|
120
|
+
const data = await res.text();
|
|
121
|
+
log.info('sender', `Batch ${batchNum}: ${batch.length} events (HTTP ${res.status})`);
|
|
122
|
+
if (res.ok) {
|
|
123
|
+
results.push({ success: true, statusCode: res.status, body: data, eventCount: batch.length });
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
if (res.status >= 500 && attempt === 0) {
|
|
127
|
+
log.warn('sender', `Batch ${batchNum} attempt ${attempt + 1} ā HTTP ${res.status}, retrying...`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
log.error('sender', `Batch ${batchNum} ā HTTP ${res.status}: ${data}`);
|
|
131
|
+
results.push({ success: false, statusCode: res.status, body: data, eventCount: batch.length });
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
catch (err) {
|
|
135
|
+
log.error('sender', `Batch ${batchNum} attempt ${attempt + 1} ā ${errMsg(err)}`);
|
|
136
|
+
if (attempt === 1) {
|
|
137
|
+
results.push({ success: false, statusCode: 0, body: errMsg(err), eventCount: batch.length });
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return results;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* reportInstance ā PUT /v1/instance
|
|
146
|
+
*
|
|
147
|
+
* Reports machine + software metadata to the Shield platform for score
|
|
148
|
+
* calculation and dashboard display. This is NOT a security event and does
|
|
149
|
+
* NOT go to Chronicle ā it goes directly to the platform API via Cloud Run.
|
|
150
|
+
*
|
|
151
|
+
* Called periodically (default: every 5 minutes) by the bridge/plugin loop.
|
|
152
|
+
*/
|
|
153
|
+
async function reportInstance(payload, credentials) {
|
|
154
|
+
const { apiUrl, instanceId, hmacSecret, shieldEnv } = credentials;
|
|
155
|
+
if (!apiUrl || !instanceId || !hmacSecret) {
|
|
156
|
+
log.warn('sender', 'reportInstance: missing credentials, skipping');
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
const nonce = generateNonce();
|
|
160
|
+
const signature = signRequest(instanceId, nonce, hmacSecret);
|
|
161
|
+
log.debug('sender', `reportInstance ā ${apiUrl}/v1/instance [env=${shieldEnv || 'dev'}]`, payload);
|
|
162
|
+
try {
|
|
163
|
+
const res = await fetchWithTimeout(`${apiUrl}/v1/instance`, {
|
|
164
|
+
method: 'PUT',
|
|
165
|
+
headers: {
|
|
166
|
+
'Content-Type': 'application/json',
|
|
167
|
+
'X-Shield-Instance-Id': instanceId,
|
|
168
|
+
'X-Shield-Nonce': nonce,
|
|
169
|
+
'X-Shield-Signature': signature,
|
|
170
|
+
'X-Shield-Version': version_1.VERSION,
|
|
171
|
+
...envHeaders(shieldEnv),
|
|
172
|
+
},
|
|
173
|
+
body: JSON.stringify(payload),
|
|
174
|
+
});
|
|
175
|
+
if (!res.ok) {
|
|
176
|
+
const body = await res.text();
|
|
177
|
+
log.warn('sender', `reportInstance HTTP ${res.status}: ${body.slice(0, 100)}`);
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
return true;
|
|
181
|
+
}
|
|
182
|
+
catch (err) {
|
|
183
|
+
log.warn('sender', `reportInstance error: ${errMsg(err)}`);
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* setup.ts ā Interactive configuration wizard for Shield
|
|
4
|
+
*
|
|
5
|
+
* Two-stage credential flow:
|
|
6
|
+
* 1. User provides a registration key from the Shield portal
|
|
7
|
+
* 2. POST /v1/register exchanges it for an HMAC signing secret
|
|
8
|
+
* 3. The returned HMAC secret + generated instance ID are saved to config.env
|
|
9
|
+
*/
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* setup.ts ā Interactive configuration wizard for Shield
|
|
5
|
+
*
|
|
6
|
+
* Two-stage credential flow:
|
|
7
|
+
* 1. User provides a registration key from the Shield portal
|
|
8
|
+
* 2. POST /v1/register exchanges it for an HMAC signing secret
|
|
9
|
+
* 3. The returned HMAC secret + generated instance ID are saved to config.env
|
|
10
|
+
*/
|
|
11
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
12
|
+
if (k2 === undefined) k2 = k;
|
|
13
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
14
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
15
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
16
|
+
}
|
|
17
|
+
Object.defineProperty(o, k2, desc);
|
|
18
|
+
}) : (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
o[k2] = m[k];
|
|
21
|
+
}));
|
|
22
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
23
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
24
|
+
}) : function(o, v) {
|
|
25
|
+
o["default"] = v;
|
|
26
|
+
});
|
|
27
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
28
|
+
var ownKeys = function(o) {
|
|
29
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
30
|
+
var ar = [];
|
|
31
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
32
|
+
return ar;
|
|
33
|
+
};
|
|
34
|
+
return ownKeys(o);
|
|
35
|
+
};
|
|
36
|
+
return function (mod) {
|
|
37
|
+
if (mod && mod.__esModule) return mod;
|
|
38
|
+
var result = {};
|
|
39
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
40
|
+
__setModuleDefault(result, mod);
|
|
41
|
+
return result;
|
|
42
|
+
};
|
|
43
|
+
})();
|
|
44
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
45
|
+
const readline = __importStar(require("readline"));
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const path_1 = require("path");
|
|
48
|
+
const os_1 = require("os");
|
|
49
|
+
const config_1 = require("./config");
|
|
50
|
+
const crypto_1 = require("crypto");
|
|
51
|
+
const rl = readline.createInterface({
|
|
52
|
+
input: process.stdin,
|
|
53
|
+
output: process.stdout
|
|
54
|
+
});
|
|
55
|
+
function prompt(question) {
|
|
56
|
+
return new Promise((resolve) => {
|
|
57
|
+
rl.question(question, (answer) => resolve(answer.trim()));
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
function generateInstanceId() {
|
|
61
|
+
const data = `${(0, os_1.hostname)()}-${(0, os_1.userInfo)().username}-${Date.now()}`;
|
|
62
|
+
return (0, crypto_1.createHash)('sha256').update(data).digest('hex');
|
|
63
|
+
}
|
|
64
|
+
async function testConnection(apiUrl) {
|
|
65
|
+
try {
|
|
66
|
+
process.stdout.write('Connecting... ');
|
|
67
|
+
const response = await fetch(`${apiUrl}/`, {
|
|
68
|
+
method: 'GET',
|
|
69
|
+
headers: {
|
|
70
|
+
'User-Agent': 'OpenClaw-Shield-Setup/1.0'
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
if (response.ok) {
|
|
74
|
+
console.log('ok');
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
console.log(`failed (HTTP ${response.status})`);
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
console.log(`failed (${error instanceof Error ? error.message : String(error)})`);
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async function registerInstance(config) {
|
|
88
|
+
try {
|
|
89
|
+
process.stdout.write('Registering instance... ');
|
|
90
|
+
// Cloud Run /v1/register expects: installation_code + fingerprint
|
|
91
|
+
const payload = {
|
|
92
|
+
installation_code: config.registrationKey,
|
|
93
|
+
fingerprint: config.instanceId,
|
|
94
|
+
machine: {
|
|
95
|
+
hostname: (0, os_1.hostname)(),
|
|
96
|
+
user: (0, os_1.userInfo)().username,
|
|
97
|
+
os: process.platform,
|
|
98
|
+
arch: process.arch,
|
|
99
|
+
node_version: process.version,
|
|
100
|
+
},
|
|
101
|
+
software: {
|
|
102
|
+
plugin_version: '0.2.8-beta',
|
|
103
|
+
instance_name: config.instanceName,
|
|
104
|
+
},
|
|
105
|
+
};
|
|
106
|
+
const response = await fetch(`${config.apiUrl}/v1/register`, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
headers: {
|
|
109
|
+
'Content-Type': 'application/json',
|
|
110
|
+
'User-Agent': 'OpenClaw-Shield-Setup/0.2',
|
|
111
|
+
},
|
|
112
|
+
body: JSON.stringify(payload),
|
|
113
|
+
signal: AbortSignal.timeout(10_000),
|
|
114
|
+
});
|
|
115
|
+
if (response.ok) {
|
|
116
|
+
const data = await response.json();
|
|
117
|
+
const hmacSecret = data.hmacSecret;
|
|
118
|
+
if (!hmacSecret) {
|
|
119
|
+
console.log('failed (no credentials returned ā contact your Shield administrator)');
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
console.log('ok');
|
|
123
|
+
return hmacSecret;
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
const body = await response.text();
|
|
127
|
+
let msg = `HTTP ${response.status}`;
|
|
128
|
+
try {
|
|
129
|
+
const parsed = JSON.parse(body);
|
|
130
|
+
msg = parsed.message || parsed.error || msg;
|
|
131
|
+
}
|
|
132
|
+
catch { /* raw */ }
|
|
133
|
+
console.log(`failed ā ${msg}`);
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
console.log(`failed ā ${error instanceof Error ? error.message : String(error)}`);
|
|
139
|
+
return null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function saveConfig(config) {
|
|
143
|
+
const configDir = (0, path_1.join)(config_1.SHIELD_CONFIG_PATH, '..');
|
|
144
|
+
if (!(0, fs_1.existsSync)(configDir)) {
|
|
145
|
+
(0, fs_1.mkdirSync)(configDir, { recursive: true });
|
|
146
|
+
}
|
|
147
|
+
const envContent = `# Shield API Configuration
|
|
148
|
+
# Generated by shield-setup on ${new Date().toISOString()}
|
|
149
|
+
# Location: ${config_1.SHIELD_CONFIG_PATH}
|
|
150
|
+
|
|
151
|
+
SHIELD_API_URL=${config.apiUrl}
|
|
152
|
+
SHIELD_INSTANCE_ID=${config.instanceId}
|
|
153
|
+
SHIELD_HMAC_SECRET=${config.hmacSecret}
|
|
154
|
+
INSTANCE_NAME=${config.instanceName}
|
|
155
|
+
|
|
156
|
+
# Optional overrides (uncomment to use)
|
|
157
|
+
# POLL_INTERVAL_MS=30000
|
|
158
|
+
# DRY_RUN=true
|
|
159
|
+
# REDACTION_ENABLED=true
|
|
160
|
+
# SESSION_DIR=/path/to/custom/sessions
|
|
161
|
+
`;
|
|
162
|
+
(0, fs_1.writeFileSync)(config_1.SHIELD_CONFIG_PATH, envContent, { encoding: 'utf-8', mode: 0o600 });
|
|
163
|
+
console.log(`ā
Configuration saved to ${config_1.SHIELD_CONFIG_PATH}`);
|
|
164
|
+
}
|
|
165
|
+
const SHIELD_API_URL = 'https://openclaw-shield.upx.com';
|
|
166
|
+
async function main() {
|
|
167
|
+
console.log('š”ļø OpenClaw Shield Setup');
|
|
168
|
+
console.log('==========================\n');
|
|
169
|
+
try {
|
|
170
|
+
const registrationKey = await prompt('Installation Key (from Shield portal): ');
|
|
171
|
+
if (!registrationKey) {
|
|
172
|
+
console.log('ā Installation key is required');
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
175
|
+
const instanceName = `openclaw-${(0, os_1.hostname)()}`;
|
|
176
|
+
const instanceId = generateInstanceId();
|
|
177
|
+
const config = {
|
|
178
|
+
apiUrl: SHIELD_API_URL,
|
|
179
|
+
registrationKey,
|
|
180
|
+
instanceName,
|
|
181
|
+
instanceId,
|
|
182
|
+
hmacSecret: '',
|
|
183
|
+
};
|
|
184
|
+
// Warn if credentials already exist
|
|
185
|
+
if ((0, fs_1.existsSync)(config_1.SHIELD_CONFIG_PATH)) {
|
|
186
|
+
const overwrite = await prompt('ā ļø Shield is already configured. Overwrite? (y/N): ');
|
|
187
|
+
if (overwrite.toLowerCase() !== 'y' && overwrite.toLowerCase() !== 'yes') {
|
|
188
|
+
console.log('Setup cancelled. Existing configuration preserved.');
|
|
189
|
+
process.exit(0);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
const connectionOk = await testConnection(SHIELD_API_URL);
|
|
193
|
+
if (!connectionOk) {
|
|
194
|
+
console.log('ā Cannot reach the Shield API. Check your internet connection and try again.');
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const exchangedSecret = await registerInstance(config);
|
|
198
|
+
if (!exchangedSecret) {
|
|
199
|
+
console.log('ā Registration failed. Please verify your installation key and try again.');
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
config.hmacSecret = exchangedSecret;
|
|
203
|
+
saveConfig(config);
|
|
204
|
+
console.log('\nā
Shield activated!');
|
|
205
|
+
console.log(' Restart your OpenClaw Gateway to start monitoring.');
|
|
206
|
+
}
|
|
207
|
+
catch (error) {
|
|
208
|
+
console.error('ā Setup failed:', error instanceof Error ? error.message : String(error));
|
|
209
|
+
process.exit(1);
|
|
210
|
+
}
|
|
211
|
+
finally {
|
|
212
|
+
rl.close();
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
process.on('SIGINT', () => {
|
|
216
|
+
console.log('\n\nSetup cancelled by user.');
|
|
217
|
+
rl.close();
|
|
218
|
+
process.exit(0);
|
|
219
|
+
});
|
|
220
|
+
if (require.main === module) {
|
|
221
|
+
main();
|
|
222
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* transformer.ts ā Thin orchestration layer
|
|
3
|
+
*
|
|
4
|
+
* Iterates raw JSONL entries, routes each tool call to the matching schema,
|
|
5
|
+
* and wraps the resulting ShieldEvent in an EnvelopeEvent for transmission.
|
|
6
|
+
*
|
|
7
|
+
* All enrichment logic lives in src/events/{type}/enrich.ts.
|
|
8
|
+
*/
|
|
9
|
+
import { RawEntry } from './fetcher';
|
|
10
|
+
import type { ShieldEvent, SourceInfo } from './events';
|
|
11
|
+
export type { SourceInfo };
|
|
12
|
+
export interface EnvelopeEvent {
|
|
13
|
+
source: SourceInfo;
|
|
14
|
+
event: ShieldEvent;
|
|
15
|
+
}
|
|
16
|
+
/** Top-level request body for POST /v1/ingest ā used for JSON Schema generation */
|
|
17
|
+
export interface IngestPayload {
|
|
18
|
+
entries: EnvelopeEvent[];
|
|
19
|
+
}
|
|
20
|
+
/** Resolve the installed OpenClaw version from known package.json paths. */
|
|
21
|
+
export declare function resolveOpenClawVersion(): string;
|
|
22
|
+
/** Resolve agent_label from IDENTITY.md in the configured workspace. */
|
|
23
|
+
export declare function resolveAgentLabel(agentId: string): string;
|
|
24
|
+
export declare function transformEntries(entries: RawEntry[]): EnvelopeEvent[];
|
|
25
|
+
/** Generate a HOST_TELEMETRY envelope with version + config info for security rules */
|
|
26
|
+
export declare function generateHostTelemetry(): EnvelopeEvent | null;
|