securenow 7.7.6 → 7.7.7
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/NPM_README.md +6 -3
- package/README.md +2 -0
- package/SKILL-API.md +19 -3
- package/SKILL-CLI.md +15 -5
- package/cli/automation.js +29 -1
- package/cli/security.js +33 -23
- package/cli.js +7 -5
- package/mcp/catalog.js +45 -13
- package/package.json +1 -1
package/NPM_README.md
CHANGED
|
@@ -186,7 +186,7 @@ codex mcp add securenow -- npx securenow mcp
|
|
|
186
186
|
npx -p securenow securenow-mcp
|
|
187
187
|
```
|
|
188
188
|
|
|
189
|
-
The MCP surface exposes tools for applications, traces, logs, firewall, IP intelligence, forensics, notifications, blocklist, allowlist, trusted IPs, and docs-backed prompts/resources. Write actions require `confirm:true` and a reason.
|
|
189
|
+
The MCP surface exposes tools for applications, traces, logs, firewall, IP intelligence, forensics, notifications, blocklist, allowlist, trusted IPs, and docs-backed prompts/resources. Write actions require `confirm:true` and a reason. Use `securenow_blocklist_unblock` to stop firewall enforcement while keeping the block report/history; `securenow_blocklist_remove` is a compatibility alias.
|
|
190
190
|
|
|
191
191
|
For hosted clients, SecureNow can expose the same surface at `https://api.securenow.ai/mcp`. The hosted endpoint uses the same API authentication and scope checks as the rest of SecureNow.
|
|
192
192
|
|
|
@@ -272,7 +272,9 @@ npx securenow ip traces 203.0.113.42
|
|
|
272
272
|
# Manage the blocklist
|
|
273
273
|
npx securenow blocklist
|
|
274
274
|
npx securenow blocklist add 203.0.113.42 --reason "Brute force scanner"
|
|
275
|
-
npx securenow blocklist
|
|
275
|
+
npx securenow blocklist unblock <id> --reason "Reviewed as safe"
|
|
276
|
+
npx securenow blocklist remove <id> # compatibility alias
|
|
277
|
+
npx securenow blocklist list --status removed
|
|
276
278
|
npx securenow blocklist stats
|
|
277
279
|
|
|
278
280
|
# Manage trusted IPs
|
|
@@ -520,7 +522,8 @@ npx securenow logs --json --level error | jq '.logs'
|
|
|
520
522
|
| | `automation dry-run <id>` | Preview automation matches without writing blocks |
|
|
521
523
|
| | `automation execute <id> --yes` | Run an automation rule now |
|
|
522
524
|
| | `blocklist add <ip>` | Block IP |
|
|
523
|
-
| | `blocklist
|
|
525
|
+
| | `blocklist unblock <id>` | Unblock IP and retain report/history |
|
|
526
|
+
| | `blocklist remove <id>` | Compatibility alias for unblock |
|
|
524
527
|
| | `blocklist stats` | Block stats |
|
|
525
528
|
| | `allowlist` | Allowed IPs (restrict-mode) |
|
|
526
529
|
| | `allowlist add <ip>` | Allow IP (`--label`, `--reason`) |
|
package/README.md
CHANGED
|
@@ -191,6 +191,7 @@ npx securenow doctor # diagnose config + connectivity
|
|
|
191
191
|
# Security
|
|
192
192
|
npx securenow firewall status --env production
|
|
193
193
|
npx securenow blocklist add 1.2.3.4 --reason "scanner"
|
|
194
|
+
npx securenow blocklist unblock <id> --reason "reviewed safe"
|
|
194
195
|
npx securenow fp ai-fill --description "Stripe webhook POST /api/stripe/webhook"
|
|
195
196
|
|
|
196
197
|
# Telemetry from shell (no SDK boot)
|
|
@@ -357,6 +358,7 @@ After install, the `securenow` CLI is available via `npx securenow` or globally
|
|
|
357
358
|
|---|---|
|
|
358
359
|
| `securenow blocklist` | List blocked IPs |
|
|
359
360
|
| `securenow blocklist add <ip> [--reason ...]` | Block an IP |
|
|
361
|
+
| `securenow blocklist unblock <id> [--reason ...]` | Stop enforcement and keep block history |
|
|
360
362
|
| `securenow allowlist add <ip>` | Allow an IP (restrict-mode) |
|
|
361
363
|
| `securenow trusted add <ip>` | Mark an IP as trusted |
|
|
362
364
|
|
package/SKILL-API.md
CHANGED
|
@@ -66,9 +66,25 @@ npx securenow api-key set snk_live_abc123...
|
|
|
66
66
|
|
|
67
67
|
Both paths write the key to `.securenow/credentials.json` (auto-gitignored) and the firewall activates on next start. For production, run `npx securenow credentials runtime --env production` and mount/copy the tokenless file as `.securenow/credentials.json`.
|
|
68
68
|
|
|
69
|
-
The firewall syncs your blocklist and enforces it on every request — zero code changes.
|
|
70
|
-
|
|
71
|
-
|
|
69
|
+
The firewall syncs your blocklist and enforces it on every request — zero code changes.
|
|
70
|
+
|
|
71
|
+
Blocklist unblocks are audit-preserving: dashboard/API/CLI/MCP unblock actions
|
|
72
|
+
mark the active block as `removed`, invalidate firewall sync, clear expiry to
|
|
73
|
+
avoid TTL deletion, and retain block reports/history for future review or
|
|
74
|
+
reblock context.
|
|
75
|
+
|
|
76
|
+
For near-realtime propagation after a block/unblock, set
|
|
77
|
+
`SECURENOW_FIREWALL_VERSION_INTERVAL=1` or `2` in the protected app. The SDK
|
|
78
|
+
polls `/firewall/sync` with ETag/304, so unchanged checks are lightweight; keep
|
|
79
|
+
`SECURENOW_FIREWALL_SYNC_INTERVAL` high as a safety-net full refresh.
|
|
80
|
+
|
|
81
|
+
Default automation is active for new and existing customers. The API
|
|
82
|
+
idempotently provisions risk-score rules for all apps/environments:
|
|
83
|
+
`riskScore >= 95` blocks for 7 days, `90-94` for 72h, and `85-89` for 24h.
|
|
84
|
+
Run `securenow automation defaults --yes` or the API backfill script when an
|
|
85
|
+
operator needs to ensure those defaults immediately.
|
|
86
|
+
|
|
87
|
+
---
|
|
72
88
|
|
|
73
89
|
## Import Map
|
|
74
90
|
|
package/SKILL-CLI.md
CHANGED
|
@@ -300,13 +300,21 @@ securenow firewall test-ip <ip> --app <key> --env local # check if IP would be
|
|
|
300
300
|
securenow blocklist # list blocked IPs
|
|
301
301
|
securenow blocklist list
|
|
302
302
|
securenow blocklist add <ip> --app <key> --env production --reason "Brute force"
|
|
303
|
-
securenow blocklist
|
|
303
|
+
securenow blocklist unblock <id> --reason "False alarm after review"
|
|
304
|
+
securenow blocklist remove <id> # compatibility alias for unblock
|
|
305
|
+
securenow blocklist list --status removed # audit retained unblocks
|
|
304
306
|
securenow blocklist stats # block counts, top reasons
|
|
305
307
|
```
|
|
306
308
|
|
|
309
|
+
Unblock stops firewall enforcement but preserves the block report, history, and
|
|
310
|
+
unblock audit fields. Reblocking the same IP later creates a fresh active block
|
|
311
|
+
without erasing the previous investigation trail.
|
|
312
|
+
|
|
307
313
|
MCP exposes legacy pending-block cleanup separately from current Requires Human
|
|
308
314
|
work:
|
|
309
315
|
|
|
316
|
+
- `securenow_blocklist_unblock`
|
|
317
|
+
- `securenow_blocklist_remove` (compatibility alias for unblock)
|
|
310
318
|
- `securenow_blocklist_pending_list`
|
|
311
319
|
- `securenow_blocklist_pending_approve`
|
|
312
320
|
- `securenow_blocklist_pending_reject`
|
|
@@ -318,15 +326,17 @@ work:
|
|
|
318
326
|
|
|
319
327
|
```bash
|
|
320
328
|
securenow automation # list blocklist automation rules
|
|
329
|
+
securenow automation defaults --yes # ensure built-in default risk-score rules
|
|
321
330
|
securenow automation show <id>
|
|
322
331
|
securenow automation dry-run <id> --limit 500
|
|
323
332
|
securenow automation execute <id> --yes
|
|
324
333
|
```
|
|
325
334
|
|
|
326
|
-
|
|
327
|
-
`riskScore
|
|
328
|
-
|
|
329
|
-
|
|
335
|
+
Built-in default automation is enabled by default for all apps/environments and
|
|
336
|
+
uses the canonical `riskScore`: 95-100 blocks for 7 days, 90-94 blocks for 72h,
|
|
337
|
+
85-89 blocks for 24h, and scores below 85 stay in investigation/review unless
|
|
338
|
+
the customer adds a stricter custom rule. Raw SecureNow IPDB confidence remains
|
|
339
|
+
supporting evidence, not the primary automation score.
|
|
330
340
|
|
|
331
341
|
### Allowlist — Restrict to Known IPs
|
|
332
342
|
|
package/cli/automation.js
CHANGED
|
@@ -249,6 +249,34 @@ async function execute(args, flags) {
|
|
|
249
249
|
}
|
|
250
250
|
}
|
|
251
251
|
|
|
252
|
+
async function defaults(args, flags) {
|
|
253
|
+
requireAuth();
|
|
254
|
+
if ((flags['force-enable'] || flags.force) && !flags.yes) {
|
|
255
|
+
const ok = await ui.confirm('Re-enable existing SecureNow default automation rules that were disabled?');
|
|
256
|
+
if (!ok) { ui.info('Cancelled'); return; }
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const s = ui.spinner('Ensuring default automation rules');
|
|
260
|
+
try {
|
|
261
|
+
const data = await api.post('/automation-rules/defaults/ensure', {
|
|
262
|
+
forceEnableExisting: !!(flags['force-enable'] || flags.force),
|
|
263
|
+
});
|
|
264
|
+
s.stop('Default automation rules ensured');
|
|
265
|
+
if (flags.json) { ui.json(data); return; }
|
|
266
|
+
|
|
267
|
+
const result = data.result || {};
|
|
268
|
+
ui.keyValue([
|
|
269
|
+
['Version', String(result.version ?? '-')],
|
|
270
|
+
['Created', String(result.created ?? 0)],
|
|
271
|
+
['Updated', String(result.updated ?? 0)],
|
|
272
|
+
['Already present', String(result.alreadyProvisioned ?? 0)],
|
|
273
|
+
]);
|
|
274
|
+
} catch (err) {
|
|
275
|
+
s.fail('Failed to ensure default automation rules');
|
|
276
|
+
throw err;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
252
280
|
async function remove(args, flags) {
|
|
253
281
|
requireAuth();
|
|
254
282
|
const id = args[0];
|
|
@@ -272,4 +300,4 @@ async function remove(args, flags) {
|
|
|
272
300
|
}
|
|
273
301
|
}
|
|
274
302
|
|
|
275
|
-
module.exports = { list, show, create, update, dryRun, execute, remove };
|
|
303
|
+
module.exports = { list, show, create, update, dryRun, execute, defaults, remove };
|
package/cli/security.js
CHANGED
|
@@ -339,6 +339,12 @@ async function blocklistList(args, flags) {
|
|
|
339
339
|
if (flags.limit) query.limit = flags.limit;
|
|
340
340
|
if (flags.app) query.appKey = flags.app;
|
|
341
341
|
if (flags.env || flags.environment) query.environment = flags.env || flags.environment;
|
|
342
|
+
if (flags.status) query.status = flags.status;
|
|
343
|
+
if (flags.search) query.search = flags.search;
|
|
344
|
+
if (flags.view) query.view = flags.view;
|
|
345
|
+
if (flags.approvalStatus || flags['approval-status']) {
|
|
346
|
+
query.approvalStatus = flags.approvalStatus || flags['approval-status'];
|
|
347
|
+
}
|
|
342
348
|
const data = await api.get('/blocklist', { query });
|
|
343
349
|
const items = data.blockedIps || [];
|
|
344
350
|
s.stop(`Found ${items.length} blocked IP${items.length !== 1 ? 's' : ''}${data.total ? ` (${data.total} total)` : ''}`);
|
|
@@ -348,15 +354,17 @@ async function blocklistList(args, flags) {
|
|
|
348
354
|
console.log('');
|
|
349
355
|
const rows = items.map(b => [
|
|
350
356
|
ui.c.dim(ui.truncate(b._id, 12)),
|
|
351
|
-
ui.c.red(b.ip || b.cidr || '—'),
|
|
352
|
-
ui.truncate(b.reason || '', 40),
|
|
357
|
+
ui.c.red(b.ip || b.cidr || '—'),
|
|
358
|
+
ui.truncate(b.reason || '', 40),
|
|
353
359
|
b.source || '—',
|
|
360
|
+
b.status || 'active',
|
|
354
361
|
b.applicationKey || ui.c.dim('all apps'),
|
|
355
362
|
b.environment || ui.c.dim('all envs'),
|
|
356
363
|
ui.timeAgo(b.createdAt),
|
|
364
|
+
b.unblockedAt ? ui.timeAgo(b.unblockedAt) : ui.c.dim('—'),
|
|
357
365
|
b.expiresAt ? new Date(b.expiresAt).toLocaleDateString() : ui.c.dim('permanent'),
|
|
358
366
|
]);
|
|
359
|
-
ui.table(['ID', 'IP/CIDR', 'Reason', 'Source', 'App', 'Env', 'Added', 'Expires'], rows);
|
|
367
|
+
ui.table(['ID', 'IP/CIDR', 'Reason', 'Source', 'Status', 'App', 'Env', 'Added', 'Unblocked', 'Expires'], rows);
|
|
360
368
|
console.log('');
|
|
361
369
|
} catch (err) {
|
|
362
370
|
s.fail('Failed to fetch blocklist');
|
|
@@ -390,26 +398,28 @@ async function blocklistAdd(args, flags) {
|
|
|
390
398
|
|
|
391
399
|
async function blocklistRemove(args, flags) {
|
|
392
400
|
requireAuth();
|
|
393
|
-
const id = args[0];
|
|
394
|
-
if (!id) {
|
|
395
|
-
ui.error('Blocklist entry ID required. Usage: securenow blocklist
|
|
396
|
-
process.exit(1);
|
|
397
|
-
}
|
|
398
|
-
|
|
399
|
-
if (!flags.force && !flags.yes) {
|
|
400
|
-
const ok = await ui.confirm('
|
|
401
|
-
if (!ok) { ui.info('Cancelled'); return; }
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
const s = ui.spinner('
|
|
405
|
-
try {
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
s.
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
401
|
+
const id = args[0];
|
|
402
|
+
if (!id) {
|
|
403
|
+
ui.error('Blocklist entry ID required. Usage: securenow blocklist unblock <id> [--reason <reason>]');
|
|
404
|
+
process.exit(1);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
if (!flags.force && !flags.yes) {
|
|
408
|
+
const ok = await ui.confirm('Unblock this IP? Firewall enforcement stops, but block report and history stay saved.');
|
|
409
|
+
if (!ok) { ui.info('Cancelled'); return; }
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
const s = ui.spinner('Unblocking IP');
|
|
413
|
+
try {
|
|
414
|
+
const body = {};
|
|
415
|
+
if (flags.reason) body.reason = flags.reason;
|
|
416
|
+
await api.post(`/blocklist/${id}/unblock`, body);
|
|
417
|
+
s.stop('Unblocked; block report and history retained');
|
|
418
|
+
} catch (err) {
|
|
419
|
+
s.fail('Failed to unblock IP');
|
|
420
|
+
throw err;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
413
423
|
|
|
414
424
|
async function blocklistStats(args, flags) {
|
|
415
425
|
requireAuth();
|
package/cli.js
CHANGED
|
@@ -255,7 +255,7 @@ const COMMANDS = {
|
|
|
255
255
|
},
|
|
256
256
|
automation: {
|
|
257
257
|
desc: 'Manage automation rules for blocklist actions',
|
|
258
|
-
usage: 'securenow automation <list|show|create|update|dry-run|execute|delete> [rule-id] [options]',
|
|
258
|
+
usage: 'securenow automation <list|defaults|show|create|update|dry-run|execute|delete> [rule-id] [options]',
|
|
259
259
|
flags: {
|
|
260
260
|
json: 'Output as JSON',
|
|
261
261
|
body: 'Full JSON body for create/update',
|
|
@@ -280,6 +280,7 @@ const COMMANDS = {
|
|
|
280
280
|
},
|
|
281
281
|
sub: {
|
|
282
282
|
list: { desc: 'List automation rules', run: (a, f) => require('./cli/automation').list(a, f) },
|
|
283
|
+
defaults: { desc: 'Ensure SecureNow default risk-score automation rules', usage: 'securenow automation defaults [--force-enable] [--yes]', run: (a, f) => require('./cli/automation').defaults(a, f) },
|
|
283
284
|
show: { desc: 'Show automation rule details', usage: 'securenow automation show <rule-id>', run: (a, f) => require('./cli/automation').show(a, f) },
|
|
284
285
|
create: { desc: 'Create automation rule', usage: 'securenow automation create --name "..." --conditions \'[...]\' --actions \'[...]\'', run: (a, f) => require('./cli/automation').create(a, f) },
|
|
285
286
|
update: { desc: 'Update automation rule', usage: 'securenow automation update <rule-id> --body \'{...}\'', run: (a, f) => require('./cli/automation').update(a, f) },
|
|
@@ -292,13 +293,14 @@ const COMMANDS = {
|
|
|
292
293
|
blocklist: {
|
|
293
294
|
desc: 'Manage IP blocklist',
|
|
294
295
|
usage: 'securenow blocklist <subcommand> [options]',
|
|
295
|
-
flags: { app: 'Scope to app key', env: 'Scope to environment', environment: 'Alias for --env', page: 'Page number', limit: 'Max results', json: 'Output as JSON' },
|
|
296
|
+
flags: { app: 'Scope to app key', env: 'Scope to environment', environment: 'Alias for --env', page: 'Page number', limit: 'Max results', status: 'Entry status: active or removed', 'approval-status': 'Approval filter: pending, approved, or rejected', search: 'IP prefix search', view: 'List view: all or operational', reason: 'Audit reason for unblock', json: 'Output as JSON' },
|
|
296
297
|
sub: {
|
|
297
298
|
list: { desc: 'List blocked IPs', run: (a, f) => require('./cli/security').blocklistList(a, f) },
|
|
298
299
|
add: { desc: 'Block an IP', usage: 'securenow blocklist add <ip> [--app <key>] [--env production] [--reason <reason>]', run: (a, f) => require('./cli/security').blocklistAdd(a, f) },
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
300
|
+
unblock: { desc: 'Unblock an IP and keep block history', usage: 'securenow blocklist unblock <id> [--reason <reason>]', run: (a, f) => require('./cli/security').blocklistRemove(a, f) },
|
|
301
|
+
remove: { desc: 'Unblock an IP (compatibility alias)', usage: 'securenow blocklist remove <id> [--reason <reason>]', run: (a, f) => require('./cli/security').blocklistRemove(a, f) },
|
|
302
|
+
stats: { desc: 'Blocklist statistics', run: (a, f) => require('./cli/security').blocklistStats(a, f) },
|
|
303
|
+
},
|
|
302
304
|
defaultSub: 'list',
|
|
303
305
|
},
|
|
304
306
|
allowlist: {
|
package/mcp/catalog.js
CHANGED
|
@@ -676,6 +676,21 @@ const TOOLS = [
|
|
|
676
676
|
endpoint: '/automation-rules',
|
|
677
677
|
inputSchema: objectSchema({}),
|
|
678
678
|
},
|
|
679
|
+
{
|
|
680
|
+
name: 'securenow_automation_defaults_ensure',
|
|
681
|
+
title: 'Ensure Default Automation Rules',
|
|
682
|
+
description: 'Create or refresh SecureNow default risk-score automation rules for the current account. Write action; requires confirmation.',
|
|
683
|
+
scope: 'automation:write',
|
|
684
|
+
readOnly: false,
|
|
685
|
+
confirm: true,
|
|
686
|
+
method: 'POST',
|
|
687
|
+
endpoint: '/automation-rules/defaults/ensure',
|
|
688
|
+
bodyFields: ['forceEnableExisting'],
|
|
689
|
+
inputSchema: objectSchema({
|
|
690
|
+
forceEnableExisting: boolean('Re-enable existing SecureNow default rules if the customer disabled them. Defaults to false.'),
|
|
691
|
+
...confirmSchema,
|
|
692
|
+
}, ['confirm', 'reason']),
|
|
693
|
+
},
|
|
679
694
|
{
|
|
680
695
|
name: 'securenow_automation_rule_get',
|
|
681
696
|
title: 'Get Automation Rule',
|
|
@@ -1040,14 +1055,31 @@ const TOOLS = [
|
|
|
1040
1055
|
},
|
|
1041
1056
|
{
|
|
1042
1057
|
name: 'securenow_blocklist_remove',
|
|
1043
|
-
title: '
|
|
1044
|
-
description: '
|
|
1058
|
+
title: 'Unblock IP (Compat Alias)',
|
|
1059
|
+
description: 'Compatibility alias for unblocking a blocklist entry while retaining block report/history. Write action; requires confirmation.',
|
|
1045
1060
|
scope: 'blocklist:write',
|
|
1046
1061
|
readOnly: false,
|
|
1047
1062
|
confirm: true,
|
|
1048
|
-
method: '
|
|
1049
|
-
endpoint: '/blocklist/:id',
|
|
1063
|
+
method: 'POST',
|
|
1064
|
+
endpoint: '/blocklist/:id/unblock',
|
|
1050
1065
|
pathParams: ['id'],
|
|
1066
|
+
bodyFields: ['reason'],
|
|
1067
|
+
inputSchema: objectSchema({
|
|
1068
|
+
id: string('Blocklist entry id.'),
|
|
1069
|
+
...confirmSchema,
|
|
1070
|
+
}, ['id', 'confirm', 'reason']),
|
|
1071
|
+
},
|
|
1072
|
+
{
|
|
1073
|
+
name: 'securenow_blocklist_unblock',
|
|
1074
|
+
title: 'Unblock IP And Keep History',
|
|
1075
|
+
description: 'Unblock a blocklist entry so firewall enforcement stops, while retaining the block report, history, and unblock audit trail. Write action; requires confirmation.',
|
|
1076
|
+
scope: 'blocklist:write',
|
|
1077
|
+
readOnly: false,
|
|
1078
|
+
confirm: true,
|
|
1079
|
+
method: 'POST',
|
|
1080
|
+
endpoint: '/blocklist/:id/unblock',
|
|
1081
|
+
pathParams: ['id'],
|
|
1082
|
+
bodyFields: ['reason'],
|
|
1051
1083
|
inputSchema: objectSchema({
|
|
1052
1084
|
id: string('Blocklist entry id.'),
|
|
1053
1085
|
...confirmSchema,
|
|
@@ -1428,16 +1460,16 @@ function promptMessages(name, args = {}) {
|
|
|
1428
1460
|
type: 'text',
|
|
1429
1461
|
text: [
|
|
1430
1462
|
'Configure SecureNow default automation using the MCP tools.',
|
|
1431
|
-
`
|
|
1432
|
-
'Use one canonical product score for automation decisions: riskScore.
|
|
1433
|
-
'
|
|
1434
|
-
'- Auto-
|
|
1435
|
-
'-
|
|
1436
|
-
'-
|
|
1437
|
-
'Start with
|
|
1438
|
-
'
|
|
1463
|
+
`Review environment context: ${environment}. Built-in defaults apply to all apps and all environments unless the customer narrows them later.`,
|
|
1464
|
+
'Use one canonical product score for automation decisions: riskScore. SecureNow IPDB / AbuseIPDB score and AI confidence remain supporting evidence.',
|
|
1465
|
+
'Built-in defaults are active by default:',
|
|
1466
|
+
'- Critical Risk Auto-Block: riskScore>=95, TTL 168h.',
|
|
1467
|
+
'- High Risk Auto-Block: riskScore>=90 AND riskScore<95, TTL 72h.',
|
|
1468
|
+
'- Elevated Risk Auto-Block: riskScore>=85 AND riskScore<90, TTL 24h.',
|
|
1469
|
+
'Start with securenow_automation_defaults_ensure({ confirm:true, reason:"Provision SecureNow default risk-score automation" }) when writes are confirmed, otherwise start with securenow_automation_rules_list and report what would be ensured.',
|
|
1470
|
+
'After ensuring defaults, dry-run each default rule with securenow_automation_rule_dry_run to inspect sample matches. Disable or tune only if evidence shows customer-specific false positives.',
|
|
1439
1471
|
confirmWrites
|
|
1440
|
-
? 'The user requested execution.
|
|
1472
|
+
? 'The user requested execution. Ensure defaults with confirm:true, do not force-enable previously disabled defaults unless the user explicitly asked, and re-list rules after writes.'
|
|
1441
1473
|
: 'Do not execute writes yet. Return exact MCP update/create calls and dry-run calls for approval.',
|
|
1442
1474
|
'End with active rules, disabled rules that should stay disabled, and any risk from automation scope.',
|
|
1443
1475
|
].join('\n'),
|
package/package.json
CHANGED