zeuslock-dlp-cli 0.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/README.md ADDED
@@ -0,0 +1,570 @@
1
+ # ZeusLock CLI
2
+
3
+ JavaScript CLI package for ZeusLock.
4
+
5
+ ## Requirements
6
+
7
+ - Node.js 22.12 or newer
8
+ - npm 10 or newer
9
+
10
+ ## Install
11
+
12
+ Install the latest release:
13
+
14
+ ```bash
15
+ npm install -g zeuslock-dlp-cli@latest
16
+ ```
17
+
18
+ Verify the installed command:
19
+
20
+ ```bash
21
+ zeuslock --version
22
+ zeuslock --help
23
+ ```
24
+
25
+ Update an existing install:
26
+
27
+ ```bash
28
+ npm install -g zeuslock-dlp-cli@latest
29
+ ```
30
+
31
+ Run without a global install:
32
+
33
+ ```bash
34
+ npm exec --package zeuslock-dlp-cli@latest -- zeuslock status
35
+ ```
36
+
37
+ ## Local Development
38
+
39
+ Install dependencies:
40
+
41
+ ```bash
42
+ npm install
43
+ ```
44
+
45
+ Run the CLI directly:
46
+
47
+ ```bash
48
+ npm start -- --help
49
+ npm start -- auth login --token zlu_your_cli_access_token
50
+ npm start -- auth login --email admin@example.com
51
+ npm start -- whoami
52
+ npm start -- status
53
+ npm start -- status --json
54
+ npm start -- auth api-key set zl_your_org_api_key
55
+ npm start -- scan ./README.md --json
56
+ npm start -- anonymize ./dataset.txt --output dataset.safe.txt
57
+ npm start -- hook install --force
58
+ npm start -- deploy gpo-config --api-key zl_your_key_here --output zeuslock-deploy
59
+ npm start -- deploy agent-verify --hostname CLIENT01
60
+ npm start -- agents list
61
+ npm start -- agents list --status offline --search linux
62
+ npm start -- extensions status
63
+ npm start -- incidents list --days 7
64
+ npm start -- incidents stats
65
+ npm start -- shadow-ai stats --days 7
66
+ npm start -- shadow-ai tools --source endpoint --status shadow
67
+ npm start -- mcp events --transport stdio --decision block
68
+ npm start -- mcp servers
69
+ npm start -- siem pull --api-key zl_your_key_here --limit 100
70
+ npm start -- status --api-key zl_your_key_here --require-license
71
+ npm start -- users list
72
+ npm start -- users remove departing@example.com --yes
73
+ npm start -- keys list --status active
74
+ npm start -- keys create --name rotation-2026-08
75
+ npm start -- keys revoke <key_id> --yes
76
+ npm start -- tokens list --status active
77
+ npm start -- tokens create --name work-laptop
78
+ npm start -- tokens revoke <token_id> --yes
79
+ npm start -- tokens purge <token_id> --yes
80
+ npm start -- rules get --output zeuslock.rules.yaml
81
+ npm start -- rules diff zeuslock.rules.yaml
82
+ ```
83
+
84
+ Install it locally as the `zeuslock` command:
85
+
86
+ ```bash
87
+ npm link
88
+ zeuslock --help
89
+ zeuslock auth login --token zlu_your_cli_access_token
90
+ zeuslock auth login --email admin@example.com
91
+ zeuslock whoami
92
+ zeuslock --token zlu_your_cli_access_token whoami
93
+ zeuslock status
94
+ zeuslock auth api-key set zl_your_org_api_key
95
+ zeuslock scan ./README.md
96
+ zeuslock scan --stdin
97
+ zeuslock anonymize ./dataset.txt --output dataset.safe.txt
98
+ zeuslock hook install
99
+ zeuslock deploy gpo-config --api-key zl_your_key_here --output zeuslock-deploy
100
+ zeuslock deploy agent-verify --hostname CLIENT01
101
+ zeuslock agents list --status online
102
+ zeuslock agents revoke <agent_id> --yes
103
+ zeuslock extensions status
104
+ zeuslock incidents list --days 7
105
+ zeuslock incidents export --days 7 --format csv --output incidents.csv
106
+ zeuslock shadow-ai stats --days 30
107
+ zeuslock shadow-ai tools --category chatbot --status shadow
108
+ zeuslock shadow-ai users --days 7
109
+ zeuslock mcp stats --days 30
110
+ zeuslock mcp events --transport stdio --method tools/call
111
+ zeuslock mcp servers
112
+ zeuslock siem pull --api-key zl_your_key_here --severity high --format json
113
+ zeuslock siem tail --api-key zl_your_key_here --category dlp
114
+ zeuslock users list --role admin
115
+ zeuslock users remove departing@example.com --yes
116
+ zeuslock keys list --status active
117
+ zeuslock keys create --name rotation-2026-08
118
+ zeuslock keys revoke <key_id> --yes
119
+ zeuslock tokens list --status active
120
+ zeuslock tokens create --name work-laptop
121
+ zeuslock tokens revoke <token_id> --yes
122
+ zeuslock tokens purge <token_id> --yes
123
+ zeuslock rules get --format json
124
+ zeuslock rules diff zeuslock.rules.yaml
125
+ ```
126
+
127
+ Run tests:
128
+
129
+ ```bash
130
+ npm test
131
+ ```
132
+
133
+ Check what would be published:
134
+
135
+ ```bash
136
+ npm run pack:dry-run
137
+ ```
138
+
139
+ ## Configuration
140
+
141
+ The CLI uses `https://api.zeuslock.ai` by default. Override the backend URL with:
142
+
143
+ ```bash
144
+ export ZEUSLOCK_API_URL="https://api.zeuslock.ai"
145
+ ```
146
+
147
+ Authenticate with a personal CLI access token generated from the dashboard CLI page:
148
+
149
+ ```bash
150
+ zeuslock auth login --token zlu_your_cli_access_token
151
+ zeuslock whoami
152
+ ```
153
+
154
+ You can also pass a CLI token for one invocation:
155
+
156
+ ```bash
157
+ zeuslock --token zlu_your_cli_access_token whoami
158
+ ```
159
+
160
+ Or authenticate with the same email/password backend flow used by the dashboard:
161
+
162
+ ```bash
163
+ zeuslock auth login --email admin@example.com
164
+ zeuslock whoami
165
+ ```
166
+
167
+ `auth login` prompts for the password when `--password` is not provided. User authentication is stored in a per-user config directory with restrictive filesystem permissions. The password is never stored.
168
+
169
+ Personal CLI access tokens use the `zlu_` prefix, authenticate as `Authorization: Bearer`, and do not refresh. If a saved CLI token is expired, revoked, or invalid, generate a new token from the dashboard CLI page and run `zeuslock auth login --token ...` again.
170
+
171
+ Clear saved user authentication with `zeuslock auth logout`. This does not clear a saved organization API key.
172
+
173
+ For automation and tests, these inputs can also be supplied through environment variables:
174
+
175
+ ```bash
176
+ export ZEUSLOCK_EMAIL="admin@example.com"
177
+ export ZEUSLOCK_PASSWORD="..."
178
+ export ZEUSLOCK_MFA_CODE="123456"
179
+ export ZEUSLOCK_API_TOKEN="zlu_your_cli_access_token"
180
+ export ZEUSLOCK_API_KEY="zl_your_org_api_key"
181
+ export ZEUSLOCK_CONFIG_DIR="/secure/custom/path"
182
+ ```
183
+
184
+ Bearer credential precedence for user-authenticated commands is:
185
+
186
+ | Source | Priority | Notes |
187
+ | --- | --- | --- |
188
+ | `zeuslock --token zlu_... <command>` | 1 | One invocation only; must appear before the subcommand. |
189
+ | `ZEUSLOCK_API_TOKEN` | 2 | Best for CI or ephemeral automation. |
190
+ | Saved CLI token | 3 | Created by `zeuslock auth login --token zlu_...`; never refreshed. |
191
+ | Saved email/password session | 4 | Created by `zeuslock auth login --email ...`; refreshes once on `401`. |
192
+
193
+ `ZEUSLOCK_API_KEY` is an organization API key from the dashboard API Keys page. SIEM pull/tail, scan, anonymize, hooks, and license validation use it as `X-API-Key`; personal CLI tokens are not used for those machine-authenticated endpoints.
194
+
195
+ You can also save the organization API key locally for scan, anonymize, hook, SIEM, and license checks:
196
+
197
+ ```bash
198
+ zeuslock auth api-key set zl_your_org_api_key
199
+ zeuslock auth api-key status
200
+ zeuslock auth api-key clear
201
+ ```
202
+
203
+ `zeuslock status` reports whether authentication is configured, checks backend `/healthz` and `/readyz`, and can validate license status when an API key is provided. It never prints token or API-key values.
204
+
205
+ ## Content Scanning, Hooks, And Anonymization
206
+
207
+ These commands use the backend surfaces already used by the dashboard, extension, and desktop agent. The CLI does not carry local DLP rules.
208
+
209
+ | Command | Purpose |
210
+ | --- | --- |
211
+ | `zeuslock scan <file\|dir>` | Upload content to `POST /api/v1/dlp/analyze` using the organization's active DLP policy. |
212
+ | `zeuslock scan --stdin` | Analyze stdin text with the same DLP endpoint. |
213
+ | `zeuslock anonymize <file>` | Send text to `POST /api/v1/anonymize` and print/write anonymized text. |
214
+ | `zeuslock hook install` | Install a Git `pre-commit` hook that runs `zeuslock hook run`. |
215
+ | `zeuslock hook run` | Scan staged Git files exactly as they will be committed. |
216
+
217
+ Supported options and values:
218
+
219
+ | Command | Option | Values |
220
+ | --- | --- | --- |
221
+ | `scan` | `--fail-on` | `alert`, `block`, `never`; default `block` |
222
+ | `scan` | `--source`, `--platform`, `--hostname`, `--path`, `--user-email` | Metadata labels sent to the backend; defaults are `source=cli`, `platform=cli`, local hostname, and `/cli/<input>` |
223
+ | `scan` | `--include-sensitive` | Includes backend anonymization maps in JSON output; hidden by default |
224
+ | `scan` | `--api-key` | Organization API key; otherwise saved key or `ZEUSLOCK_API_KEY` |
225
+ | `anonymize` | `--output` | Output file path; stdout by default |
226
+ | `anonymize` | `--include-sensitive-map` | Includes original-to-masked substitutions in JSON output; hidden by default |
227
+ | `hook install` | `--repo` | Git repository path; default current directory |
228
+ | `hook install` | `--fail-on` | `alert` or `block`; default `alert` |
229
+ | `hook install` | `--force` | Replace an existing `.git/hooks/pre-commit` |
230
+ | `hook run` | `--fail-on` | `alert`, `block`, `never`; default `alert` |
231
+
232
+ Hardcoded backend-parity values:
233
+
234
+ | Value | Used by |
235
+ | --- | --- |
236
+ | 5 files per upload batch | Matches the backend DLP analyze default file limit. |
237
+ | `source=cli` | Manual scan incidents. |
238
+ | `source=git_pre_commit`, `platform=git`, `method=PRE_COMMIT` | Git hook scan incidents. |
239
+
240
+ Skipped because the dashboard/backend do not expose them:
241
+
242
+ | Skipped command/workflow | Reason |
243
+ | --- | --- |
244
+ | Local/offline scan | No dashboard/backend source-of-truth implementation. |
245
+ | Rule override flags such as `--rule` or `--severity` on `scan` | Rules are controlled by dashboard Policies/Rules, not per CLI request. |
246
+ | No-report/dry-run scan | `POST /api/v1/dlp/analyze` persists incidents on alert/block. |
247
+ | PDF/image/Office anonymization | `/api/v1/anonymize` accepts text JSON only; file parsing belongs to scan. |
248
+
249
+ ## Fleet Deployment And Onboarding
250
+
251
+ Deployment commands mirror only the dashboard Extension page and Agents deployment modal. They generate local artifacts from existing dashboard data and APIs; they do not change the backend.
252
+
253
+ | Command | Purpose |
254
+ | --- | --- |
255
+ | `zeuslock deploy gpo-config` | Generate dashboard-supported extension GPO policy files and desktop-agent config files. |
256
+ | `zeuslock deploy agent-verify` | Verify installed/enrolled/reachable state from `GET /api/agents`. |
257
+
258
+ Supported filters and values:
259
+
260
+ | Command | Option | Values |
261
+ | --- | --- | --- |
262
+ | `deploy gpo-config` | `--artifact` | `all`, `extension`, `agent`; default `all` |
263
+ | `deploy gpo-config` | `--browser` | `all`, `chrome`, `edge`; default `all`; applies to extension artifacts |
264
+ | `deploy gpo-config` | `--output` | Output directory; default `zeuslock-deploy` |
265
+ | `deploy gpo-config` | `--api-key` | Full organization API key to embed in generated files |
266
+ | `deploy gpo-config` | `--key-id` | Existing key id from `zeuslock keys list --show-secret`; requires a decryptable key from `GET /api/keys` |
267
+ | `deploy gpo-config` | `--create-key-name` | Creates a new key with `POST /api/keys` and embeds the returned full key |
268
+ | `deploy gpo-config` | `--json` | Prints generated artifact metadata without secret values |
269
+ | `deploy agent-verify` | `--agent-id` | Exact agent id from `zeuslock agents list` |
270
+ | `deploy agent-verify` | `--hostname` | Exact hostname, case-insensitive |
271
+ | `deploy agent-verify` | `--platform` | `windows`, `macos`, `linux` |
272
+ | `deploy agent-verify` | `--status` | `online`, `offline`, `any`; default `online` |
273
+ | `deploy agent-verify` | `--json` | Prints verification metadata and matching agent rows |
274
+
275
+ Generated artifacts:
276
+
277
+ | Artifact | Generated when | Contents |
278
+ | --- | --- | --- |
279
+ | `extension/chrome-extension-forcelist.txt` | `--artifact all/extension`, Chrome | Dashboard extension force-install value. |
280
+ | `extension/chrome-extension-settings.json` | `--artifact all/extension`, Chrome | Dashboard `ExtensionSettings` JSON. |
281
+ | `extension/edge-extension-forcelist.txt` | `--artifact all/extension`, Edge | Dashboard extension force-install value. |
282
+ | `extension/edge-extension-settings.json` | `--artifact all/extension`, Edge | Dashboard `ExtensionSettings` JSON. |
283
+ | `agent/windows-agent-policy.reg` | `--artifact all/agent` | `HKLM\SOFTWARE\Policies\ZeusLock` values for `ServerUrl` and `LicenseKey`. |
284
+ | `agent/agent-config.json` | `--artifact all/agent` | Agent config with `ServerUrl`, `LicenseKey`, `apiUrl`, and `apiKey`. |
285
+ | `deployment-summary.json` | Always | Non-secret summary of org, selected key, requested options, generated files, and skipped items. |
286
+
287
+ Hardcoded dashboard parity values:
288
+
289
+ | Value | Used by |
290
+ | --- | --- |
291
+ | `hgooghpcnalhpjbemnnmdoabfjhchoip` | Published Chrome Web Store extension id. |
292
+ | `https://clients2.google.com/service/update2/crx` | Chrome/Edge extension force-install update URL. |
293
+ | `monitor_clipboard=true`, `monitor_ai_apps=true`, `show_notifications=true` | Extension configuration defaults from the dashboard. |
294
+ | `business`, `enterprise` | Plans allowed to generate extension GPO artifacts, matching the dashboard gate. |
295
+ | 5 minutes | Fallback online window when `GET /api/agents` does not include `is_online`. |
296
+
297
+ Skipped because the dashboard/backend do not expose them:
298
+
299
+ | Skipped command/workflow | Reason |
300
+ | --- | --- |
301
+ | Proxy `.reg` artifact | No dashboard UI or backend API exposes proxy registry policy values. |
302
+ | Local post-GPO machine checks | No API exposes `gpresult`, registry, package, or service state from client machines. |
303
+ | Dedicated agent verification endpoint | The backend has no dashboard-used `agent-verify` endpoint; verification uses `GET /api/agents`. |
304
+ | Non-dashboard installer/platform artifact generation | The dashboard/backend expose only the documented extension policy and agent config/install guidance. |
305
+
306
+ ## Access Governance
307
+
308
+ Access governance commands mirror the dashboard Users and API Keys pages. The dashboard/backend are the source of truth: the CLI only uses existing API behavior and applies filters locally when the API does not expose server-side filters.
309
+
310
+ | Command | Purpose |
311
+ | --- | --- |
312
+ | `zeuslock users list` | List organization users from `GET /api/users`. |
313
+ | `zeuslock users remove <user>` | Remove one user with `DELETE /api/users/{user_id}` after resolving `<user>` from `GET /api/users`. |
314
+ | `zeuslock keys list` | List API keys from `GET /api/keys`. |
315
+ | `zeuslock keys create --name <name>` | Create an API key with `POST /api/keys`. |
316
+ | `zeuslock keys revoke <key_id>` | Revoke an active API key with `DELETE /api/keys/{key_id}`. |
317
+ | `zeuslock tokens list` | List personal CLI access tokens from `GET /api/v1/cli-tokens`. |
318
+ | `zeuslock tokens create --name <name>` | Create a CLI access token with `POST /api/v1/cli-tokens`. |
319
+ | `zeuslock tokens revoke <token_id>` | Revoke a CLI access token with `DELETE /api/v1/cli-tokens/{token_id}`. |
320
+ | `zeuslock tokens purge <token_id>` | Permanently delete an already-revoked CLI access token with `DELETE /api/v1/cli-tokens/{token_id}?purge=true`. |
321
+
322
+ Supported filters and values:
323
+
324
+ | Command | Option | Values |
325
+ | --- | --- | --- |
326
+ | `users list` | `--search` | Any text; searches email, role, status, and display name locally |
327
+ | `users list` | `--role` | Values returned by `GET /api/users/roles`; typically `admin`, `user`, `viewer`, `viewer_user` depending on plan |
328
+ | `users list` | `--json` | Prints totals, filters, available role values, and normalized user rows |
329
+ | `users remove` | `<user>` | User id, `user_id`, or email from `users list` |
330
+ | `users remove` | `--yes` | Skips the confirmation prompt |
331
+ | `users remove` | `--json` | Prints the removal result |
332
+ | `keys list` | `--status` | `all`, `active`, `revoked`; default `all` |
333
+ | `keys list` | `--show-secret` | Shows returned full key values when the backend includes them; hidden by default |
334
+ | `keys list` | `--json` | Prints totals, filters, and normalized key rows |
335
+ | `keys create` | `--name` | Required key name |
336
+ | `keys create` | `--json` | Prints the created key, including the returned full key |
337
+ | `keys revoke` | `<key_id>` | API key id from `keys list` |
338
+ | `keys revoke` | `--yes` | Skips the confirmation prompt |
339
+ | `keys revoke` | `--json` | Prints the revoke result |
340
+ | `tokens list` | `--status` | `all`, `active`, `revoked`, `expired`; default `all` |
341
+ | `tokens list` | `--show-secret` | Shows returned full token values when the backend includes them; hidden by default |
342
+ | `tokens list` | `--json` | Prints totals, filters, and normalized token rows |
343
+ | `tokens create` | `--name` | Required token name, 1-255 chars |
344
+ | `tokens create` | `--expires-in-days` | Optional integer from 1 to 365; backend default is 90 when omitted |
345
+ | `tokens create` | `--json` | Prints the created token, including the returned full token |
346
+ | `tokens revoke` | `<token_id>` | CLI token id from `tokens list` |
347
+ | `tokens revoke` | `--yes` | Skips the confirmation prompt |
348
+ | `tokens revoke` | `--json` | Prints the revoke result |
349
+ | `tokens purge` | `<token_id>` | Already-revoked CLI token id from `tokens list` |
350
+ | `tokens purge` | `--yes` | Skips the confirmation prompt |
351
+ | `tokens purge` | `--json` | Prints the purge result |
352
+
353
+ Hard-coded CLI safety behavior:
354
+
355
+ | Area | Behavior |
356
+ | --- | --- |
357
+ | User removal | Refuses to remove the currently authenticated user. |
358
+ | User removal | Refuses to remove the last active admin, matching the dashboard UI guard. |
359
+ | API key listing | Full keys are hidden unless `--show-secret` is provided. |
360
+ | API key revocation | Refuses already-revoked keys because the dashboard backend uses a second `DELETE` as permanent deletion. |
361
+ | CLI token listing | Full tokens are hidden unless `--show-secret` is provided. |
362
+ | CLI token purge | Refuses active tokens; revoke first, then purge. |
363
+
364
+ Skipped because the dashboard/backend do not expose them:
365
+
366
+ | Skipped command/workflow | Reason |
367
+ | --- | --- |
368
+ | `zeuslock users remove --file departures.csv` | No dashboard/backend bulk-remove endpoint. Script repeated single-user removals externally if needed. |
369
+ | `zeuslock keys rotate` | No atomic rotation endpoint; use create, deploy the new key, then revoke the old key. |
370
+ | `zeuslock keys delete` | Not part of the requested feature and easy to confuse with revoke. |
371
+ | `zeuslock tokens rotate` | No atomic CLI-token rotation endpoint; create a new token, update callers, then revoke the old token. |
372
+ | `zeuslock users invite` / bulk invite | Available in the dashboard, but outside the attached access-governance command list. |
373
+
374
+ ## Fleet Visibility
375
+
376
+ Fleet visibility commands mirror the dashboard/backend agent and extension APIs.
377
+
378
+ | Command | Purpose |
379
+ | --- | --- |
380
+ | `zeuslock agents list` | List desktop agents from `GET /api/agents`. |
381
+ | `zeuslock agents revoke <agent_id>` | Revoke an agent with `DELETE /api/agents/{agent_id}`. |
382
+ | `zeuslock extensions status` | Show active browser extensions from `GET /api/extensions`. |
383
+
384
+ Supported filters and values:
385
+
386
+ | Command | Option | Values |
387
+ | --- | --- | --- |
388
+ | `agents list` | `--status` | `all`, `online`, `offline`; default `all` |
389
+ | `agents list` | `--search` | Any text; searches hostname and platform |
390
+ | `agents list` | `--json` | Prints summary and normalized agent rows |
391
+ | `agents revoke` | `--yes` | Skips the confirmation prompt |
392
+ | `agents revoke` | `--json` | Prints the revoke result |
393
+ | `extensions status` | `--json` | Prints summary and normalized extension rows |
394
+
395
+ `agents list` fetches `GET /api/v1/agents/downloads` best-effort to mark rows with `update_available`, matching the dashboard update badge. It does not expose an outdated-only filter because the dashboard does not.
396
+
397
+ `zeuslock report coverage` is not implemented because the dashboard/backend do not expose expected endpoint inventory, AD/Intune/MDM cross-reference data, or unprotected endpoint reporting.
398
+
399
+ ## Incidents
400
+
401
+ The incidents commands mirror the dashboard and use the same authenticated backend APIs.
402
+
403
+ | Command | Purpose |
404
+ | --- | --- |
405
+ | `zeuslock incidents list` | List incidents from `GET /api/incidents?days=N`. |
406
+ | `zeuslock incidents stats` | Show incident statistics from `GET /api/stats?days=N`. |
407
+ | `zeuslock incidents export` | Export dashboard-filtered incident data from `GET /api/incidents?days=N`. |
408
+
409
+ Supported filters and values:
410
+
411
+ | Command | Option | Values |
412
+ | --- | --- | --- |
413
+ | `incidents list` | `--days` | `7`, `30`, `90`; `90` requires Business or Enterprise |
414
+ | `incidents list` | `--severity` | `critical`, `warning`; `warning` includes high, medium, and low |
415
+ | `incidents list` | `--search` | Any text; searches user email, URL, and finding type |
416
+ | `incidents list` | `--jailbreak` | Only incidents with a `jailbreak_attempt` finding |
417
+ | `incidents stats` | `--days` | `1`, `7`, `30`, `365`; `365` requires Business or Enterprise |
418
+ | `incidents export` | `--days` | `7`, `30`, `90`; default `30`; export requires Business or Enterprise |
419
+ | `incidents export` | `--severity` | `critical`, `warning`; `warning` includes high, medium, and low |
420
+ | `incidents export` | `--search` | Any text; searches user email, URL, and finding type |
421
+ | `incidents export` | `--jailbreak` | Only incidents with a `jailbreak_attempt` finding |
422
+ | `incidents export` | `--format` | `csv`, `json`; default `csv` |
423
+ | `incidents export` | `--output` | Optional output file path; defaults to `incidents-<timestamp>.<format>` |
424
+
425
+ `zeuslock incidents export` intentionally does not support arbitrary day values or `--from`/`--to`: the dashboard exposes only 7, 30, and 90-day windows. Server-side archived export history and `zeuslock report weekly` are not implemented because the dashboard does not expose those features.
426
+
427
+ ## Shadow AI And MCP Monitoring
428
+
429
+ Shadow AI and MCP commands mirror the dashboard pages and use only existing dashboard read APIs. They first read `GET /api/org` and follow the same feature-flag behavior as the dashboard: Shadow AI is available only when `settings.shadow_ai_enabled` is true; MCP is available unless `settings.mcp_enabled` is explicitly false.
430
+
431
+ | Command | Purpose |
432
+ | --- | --- |
433
+ | `zeuslock shadow-ai stats` | Show Shadow AI KPI totals from `GET /api/shadow-ai/stats`. |
434
+ | `zeuslock shadow-ai tools` | List detected AI tools from `GET /api/shadow-ai/tools`. |
435
+ | `zeuslock shadow-ai users` | List users with shadow-tool usage from `GET /api/shadow-ai/users`. |
436
+ | `zeuslock mcp stats` | Show MCP KPI totals from `GET /api/v1/mcp/stats`. |
437
+ | `zeuslock mcp events` | List sanitized MCP metadata events from `GET /api/v1/mcp/events`. |
438
+ | `zeuslock mcp servers` | List discovered MCP server inventory from `GET /api/v1/mcp/servers`. |
439
+
440
+ Supported filters and values:
441
+
442
+ | Command | Option | Values |
443
+ | --- | --- | --- |
444
+ | `shadow-ai stats/tools` | `--days` | `7`, `30`, `90`; default `30` |
445
+ | `shadow-ai stats/tools` | `--source` | `all`, `endpoint`, `browser`, `both`; default `all` |
446
+ | `shadow-ai stats/tools` | `--status` | `all`, `sanctioned`, `shadow`; default `all` |
447
+ | `shadow-ai stats/tools` | `--category` | `all`, `chatbot`, `coding_assistant`, `image_gen`, `agent`, `other`; default `all` |
448
+ | `shadow-ai users` | `--days` | `7`, `30`, `90`; default `30` |
449
+ | `mcp stats/events` | `--days` | `7`, `30`, `90`; default `30` |
450
+ | `mcp events` | `--transport` | `all`, `http`, `sse`, `stdio`; default `all` |
451
+ | `mcp events` | `--direction` | `all`, `client_to_server`, `server_to_client`; default `all` |
452
+ | `mcp events` | `--decision` | `all`, `allow`, `alert`, `block`; default `all` |
453
+ | `mcp events` | `--method` | Any backend MCP method string, for example `tools/call`; omitted means all |
454
+ | `mcp events` | `--search` | Any text; searches server, tool, user, method, hostname, or path |
455
+ | `mcp events` | `--cursor` | Opaque `next_cursor` from a previous `mcp events --json` response |
456
+ | all Shadow AI/MCP commands | `--json` | Prints normalized JSON with filters and data |
457
+
458
+ Hardcoded dashboard parity values:
459
+
460
+ | Value | Used by |
461
+ | --- | --- |
462
+ | `limit=50` | `mcp events`, matching the dashboard page size |
463
+ | `days=90` | `mcp servers`, matching the dashboard server inventory load |
464
+ | `settings.shadow_ai_enabled` | Shadow AI feature gate; missing or false means disabled |
465
+ | `settings.mcp_enabled !== false` | MCP feature gate; missing means enabled |
466
+ | Metadata-only MCP rows | MCP event output; raw prompts/content are not exposed |
467
+
468
+ Skipped because the dashboard/backend do not expose them:
469
+
470
+ | Skipped command/workflow | Reason |
471
+ | --- | --- |
472
+ | Full user-to-all-tools matrix | Dashboard user table exposes user, distinct tool count, and most-used tool only. |
473
+ | Dedicated Shadow AI or MCP export command | Dashboard export is client-side only; the backend has no export endpoint for these pages. Use `--json` for scriptable output. |
474
+ | Raw MCP prompt/content inspection | Backend stores sanitized metadata and non-reversible content hashes only. |
475
+ | Shadow AI policy mutation | The dashboard modal exposes policy changes, but the requested CLI surface only covers stats, tools, and users. |
476
+
477
+ ## SIEM Integration And Monitoring
478
+
479
+ SIEM commands use the backend pull API shown on the dashboard SIEM page. Events are OCSF DLP events and are authenticated with an organization API key, not a dashboard user JWT.
480
+
481
+ | Command | Purpose |
482
+ | --- | --- |
483
+ | `zeuslock siem pull` | Retrieve one page of SIEM events from `GET /api/v1/siem/events`. |
484
+ | `zeuslock siem tail` | Poll `GET /api/v1/siem/events` continuously with a persisted cursor. |
485
+ | `zeuslock status` | Check CLI context, backend health/readiness, and optional license validity. |
486
+
487
+ Supported filters and values:
488
+
489
+ | Command | Option | Values |
490
+ | --- | --- | --- |
491
+ | `siem pull` | `--api-key` | Organization API key; defaults to `ZEUSLOCK_API_KEY` |
492
+ | `siem pull` | `--since` | Backend `next_cursor` string |
493
+ | `siem pull` | `--from`, `--to` | Backend-parseable ISO date/time or epoch |
494
+ | `siem pull` | `--days` | Positive integer; CLI converts to `start_time`; mutually exclusive with `--from` |
495
+ | `siem pull` | `--category` | Generic backend category string; current dashboard SIEM events use `dlp` |
496
+ | `siem pull` | `--severity` | `unknown`, `low`, `medium`, `high`, `critical`; backend treats this as minimum severity |
497
+ | `siem pull` | `--limit` | `1` to `500`; backend default is `100` |
498
+ | `siem pull` | `--format` | `jsonl`, `json`; default `jsonl` |
499
+ | `siem tail` | `--api-key`, `--since`, `--category`, `--severity`, `--limit` | Same meaning as `siem pull` |
500
+ | `siem tail` | `--interval` | Positive seconds; default `5` |
501
+ | `siem tail` | `--cursor-name` | Any stable namespace; default `default` |
502
+ | `siem tail` | `--reset-cursor` | Ignore the saved cursor for this run |
503
+ | `status` | `--api-key` | Organization API key; defaults to `ZEUSLOCK_API_KEY` |
504
+ | `status` | `--require-license` | Exit nonzero unless health, readiness, and license validation pass |
505
+ | `status` | `--json` | Print machine-readable output |
506
+
507
+ Hardcoded values:
508
+
509
+ | Value | Used by |
510
+ | --- | --- |
511
+ | `/api/v1/siem/events` | SIEM pull/tail event source |
512
+ | `X-API-Key` | SIEM and license API-key authentication header |
513
+ | `500` | Maximum SIEM page size accepted by the backend |
514
+ | `100` | Backend default SIEM page size when `--limit` is omitted |
515
+ | `5 seconds` | Default `siem tail` poll interval |
516
+ | `siem-cursors.json` | Local cursor store under the CLI config directory |
517
+ | `/healthz` and `/readyz` | Backend health and readiness checks |
518
+ | `/api/v1/validate-license` | API-key license validation endpoint |
519
+
520
+ Skipped because the dashboard/backend do not expose them:
521
+
522
+ | Skipped command/workflow | Reason |
523
+ | --- | --- |
524
+ | QRadar-specific destination setup | Dashboard/backend destinations are Splunk HEC, Microsoft Sentinel, and Elastic Bulk API only. |
525
+ | True streaming over SSE/WebSocket | Backend exposes pull pagination only, so `tail` is implemented as polling. |
526
+ | Backend-side `days` query parameter | Backend supports time filters, so CLI `--days` is converted to `start_time`. |
527
+
528
+ ## DLP Rules Policy-as-Code
529
+
530
+ The rules commands mirror the dashboard's current Policies page and existing backend APIs. They are read-only: export and diff are implemented in the CLI from existing read endpoints, and no backend import/apply endpoint is called.
531
+
532
+ | Command | Purpose |
533
+ | --- | --- |
534
+ | `zeuslock rules get` | Export policy/rules state as YAML or JSON. |
535
+ | `zeuslock rules diff [file]` | Compare a local YAML/JSON rules file against live dashboard/backend state. |
536
+
537
+ Supported filters and values:
538
+
539
+ | Command | Option | Values |
540
+ | --- | --- | --- |
541
+ | `rules get` | `--scope` | `policies`, `default`, `policy`; default `policies` |
542
+ | `rules get` | `--policy-id` | Required only with `--scope policy` |
543
+ | `rules get` | `--format` | `yaml`, `json`; default `yaml` |
544
+ | `rules get` | `--output` | Optional output file path; defaults to stdout |
545
+ | `rules diff` | `[file]` | YAML or JSON file; defaults to `zeuslock.rules.yaml`, `zeuslock.rules.yml`, then `zeuslock.rules.json` |
546
+ | `rules diff` | `--scope` | `policies`, `default`, `policy`; default `policies` |
547
+ | `rules diff` | `--policy-id` | Required only with `--scope policy` |
548
+ | `rules diff` | `--format` | `text`, `json`; default `text` |
549
+
550
+ Rules export scopes:
551
+
552
+ | Scope | Backend APIs |
553
+ | --- | --- |
554
+ | `policies` | `GET /api/policies` plus `GET /api/groups`; exports the visible dashboard policy system. |
555
+ | `default` | `GET /api/rules`; exports the org-wide Default Policy ruleset used by the frozen rules contract. |
556
+ | `policy` | `GET /api/policies/{policy_id}`; exports one policy. |
557
+
558
+ `rules diff` exits with status code `1` when differences are found. Rule import/apply, policy publishing, and backend-side diff are not implemented because the dashboard/backend do not expose policy-as-code import/apply or diff features.
559
+
560
+ ## Publishing
561
+
562
+ This package is configured as `zeuslock-dlp-cli` and exposes the executable command `zeuslock`.
563
+
564
+ Before publishing, confirm that the npm account is the intended package owner, choose the final license, and verify that `package.json` is already at the intended release version. Then run:
565
+
566
+ ```bash
567
+ npm publish --access public
568
+ ```
569
+
570
+ For production releases, prefer npm Trusted Publishing from GitHub Actions instead of storing a long-lived npm token.
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { run } from "../src/cli.js";
4
+
5
+ run(process.argv).catch((error) => {
6
+ const message = error instanceof Error ? error.message : String(error);
7
+ console.error(message);
8
+ process.exitCode = 1;
9
+ });
package/package.json ADDED
@@ -0,0 +1,33 @@
1
+ {
2
+ "name": "zeuslock-dlp-cli",
3
+ "version": "0.2.0",
4
+ "description": "Command line tools for ZeusLock.",
5
+ "type": "module",
6
+ "bin": {
7
+ "zeuslock": "bin/zeuslock.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "src",
12
+ "README.md"
13
+ ],
14
+ "scripts": {
15
+ "start": "node ./bin/zeuslock.js",
16
+ "test": "node --test",
17
+ "test:cli": "node ./bin/zeuslock.js --help && node ./bin/zeuslock.js status --json",
18
+ "pack:dry-run": "npm pack --dry-run"
19
+ },
20
+ "engines": {
21
+ "node": ">=22.12.0"
22
+ },
23
+ "keywords": [
24
+ "zeuslock",
25
+ "cli",
26
+ "security"
27
+ ],
28
+ "license": "UNLICENSED",
29
+ "dependencies": {
30
+ "commander": "^15.0.0",
31
+ "yaml": "^2.9.0"
32
+ }
33
+ }