securenow 7.7.16 → 8.0.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/NPM_README.md +44 -36
- package/README.md +56 -38
- package/SKILL-API.md +51 -27
- package/SKILL-CLI.md +67 -45
- package/app-config.js +90 -160
- package/cli/apiKey.js +21 -12
- package/cli/apps.js +3 -3
- package/cli/auth.js +114 -32
- package/cli/client.js +14 -13
- package/cli/config.js +219 -52
- package/cli/credentials.js +4 -4
- package/cli/diagnostics.js +5 -6
- package/cli/firewall.js +19 -7
- package/cli/human.js +13 -8
- package/cli/init.js +5 -5
- package/cli/run.js +1 -5
- package/cli/security.js +31 -11
- package/cli/utils.js +2 -3
- package/cli.js +68 -35
- package/console-instrumentation.js +1 -1
- package/firewall-only.js +7 -11
- package/firewall.js +110 -35
- package/mcp/catalog.js +582 -45
- package/mcp/server.js +73 -12
- package/nextjs-auto-capture.js +3 -6
- package/nextjs-middleware.js +2 -4
- package/nextjs-wrapper.js +3 -6
- package/nextjs.js +4 -11
- package/nuxt-server-plugin.mjs +7 -4
- package/otel-defaults.js +11 -0
- package/package.json +3 -3
- package/rate-limits.js +0 -2
- package/register-vite.js +5 -12
- package/register.js +5 -13
- package/resolve-ip.js +1 -1
- package/tracing.d.ts +1 -1
- package/tracing.js +6 -3
- package/web-vite.mjs +58 -62
package/SKILL-API.md
CHANGED
|
@@ -4,7 +4,7 @@ Instrument any Node.js application with OpenTelemetry tracing, structured loggin
|
|
|
4
4
|
|
|
5
5
|
**CLI parity:** every capability exposed below (redaction, CIDR matching, log/span emission, firewall preload, config inspection) has an equivalent `securenow` CLI command. See [SKILL-CLI.md](./SKILL-CLI.md) for the terminal surface.
|
|
6
6
|
|
|
7
|
-
**MCP parity (
|
|
7
|
+
**MCP parity (v8.0+):** `npx securenow mcp` starts a local stdio MCP server for Codex, Claude, and other MCP clients. It reads admin/control-plane auth from `.securenow/admin.json` and SDK runtime app credentials from `.securenow/runtime.json`, with legacy `.securenow/credentials.json` still supported. Alert-rule operators can inspect notifications, read exact `metadata.matchedSubdetectors`, dry-run candidate SQL with `securenow_alert_rule_candidate_test`, and apply global system-rule query fixes with `securenow_alert_rule_query_update` only when the admin user/plan permits it.
|
|
8
8
|
|
|
9
9
|
**Noisy alert-rule reviews:** prefer fixing a generic system-rule detector over creating customer-specific false positives. Dry-run candidate SQL first, preserve tenant scoping with `__USER_APP_KEYS__`, keep exploit-specific indicators, then save the shared query mapping only with an audit reason and explicit confirmation.
|
|
10
10
|
|
|
@@ -27,10 +27,12 @@ npm install securenow@latest
|
|
|
27
27
|
node -p "require('./node_modules/securenow/package.json').version"
|
|
28
28
|
npx securenow version
|
|
29
29
|
npx securenow login
|
|
30
|
+
npx securenow admin login # admin/control-plane CLI + MCP auth only
|
|
31
|
+
npx securenow app connect # SDK runtime app + runtime API key only
|
|
30
32
|
npx securenow init
|
|
31
33
|
```
|
|
32
34
|
|
|
33
|
-
Use `securenow@7.
|
|
35
|
+
Use `securenow@7.8.0` or newer for split admin/runtime credentials. Start authentication with `npx securenow login`; do not manually open auth URLs, because the CLI generates the callback/state values. The friendly login flow can connect both lanes, while `npx securenow admin login` only writes `.securenow/admin.json` and `npx securenow app connect` only writes `.securenow/runtime.json`. `init` scaffolds the framework integration.
|
|
34
36
|
|
|
35
37
|
### 2. Run With Instrumentation
|
|
36
38
|
|
|
@@ -54,19 +56,21 @@ npx securenow init
|
|
|
54
56
|
|
|
55
57
|
That's it. Traces, logs, request body capture, multipart metadata capture, and firewall enforcement are on by default. No code changes for Express, Fastify, NestJS, Koa, Hapi, and raw Node.
|
|
56
58
|
|
|
59
|
+
Metrics export is off by default. SecureNow sets `OTEL_METRICS_EXPORTER=none` only when the app has not explicitly configured a metrics exporter, so `@opentelemetry/sdk-node` will not start a default metrics reader that retries `localhost:4318`.
|
|
60
|
+
|
|
57
61
|
### 3. Firewall Is Enabled by Default
|
|
58
62
|
|
|
59
|
-
Since
|
|
60
|
-
the user picks or creates an app. The
|
|
61
|
-
|
|
63
|
+
Since v8.0, the app runtime flow connects the firewall automatically after
|
|
64
|
+
the user picks or creates an app. The runtime API key lives in `.securenow/runtime.json`
|
|
65
|
+
so admin CLI/MCP login cannot overwrite it:
|
|
62
66
|
|
|
63
67
|
```bash
|
|
64
|
-
npx securenow
|
|
68
|
+
npx securenow app connect # pick/create app; runtime API key is minted automatically
|
|
65
69
|
# or, if you already have one:
|
|
66
70
|
npx securenow api-key set snk_live_abc123...
|
|
67
71
|
```
|
|
68
72
|
|
|
69
|
-
Both paths write the key to `.securenow/
|
|
73
|
+
Both paths write the key to `.securenow/runtime.json` (gitignored via credential-file patterns, not a whole-directory `.securenow/` ignore) 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` or `.securenow/credentials.<env>.json`.
|
|
70
74
|
|
|
71
75
|
The firewall syncs your blocklist and enforces it on every request — zero code changes.
|
|
72
76
|
|
|
@@ -77,7 +81,7 @@ reblock context.
|
|
|
77
81
|
|
|
78
82
|
For near-realtime propagation after a block/unblock, set
|
|
79
83
|
`config.firewall.versionCheckInterval` to `1` or `2` in the protected app's
|
|
80
|
-
`.securenow/
|
|
84
|
+
`.securenow/runtime.json` or production runtime credentials. The SDK polls `/firewall/sync` with ETag/304, so
|
|
81
85
|
unchanged checks are lightweight; keep `config.firewall.syncInterval` high as a
|
|
82
86
|
safety-net full refresh.
|
|
83
87
|
|
|
@@ -103,7 +107,7 @@ operator needs to ensure those defaults immediately.
|
|
|
103
107
|
| `securenow/nuxt` | Nuxt 3 module (add to `modules` array) | ESM |
|
|
104
108
|
| `securenow/firewall` | Standalone firewall; exports `init()`, `shutdown()`, `getStats()`, `getMatcher()`, `getAllowlistMatcher()` | CJS |
|
|
105
109
|
| `securenow/rate-limits` | Rate-limit remediation API helper; exports `parseRateLimitText()`, `createRateLimitFromText()`, `createRateLimit()`, `listRateLimits()` | CJS |
|
|
106
|
-
| `securenow/firewall-only` | Preload:
|
|
110
|
+
| `securenow/firewall-only` | Preload: credentials-file firewall only, no tracing | Preload (`-r`) |
|
|
107
111
|
| `securenow/cidr` | CIDR utilities; exports `createMatcher()`, `ipToInt()`, `parseCidr()`, `matchesCidr()` | CJS |
|
|
108
112
|
| `securenow/resolve-ip` | IP resolution; exports `resolveClientIp()`, `resolveSocketIp()`, `isFromTrustedProxy()` | CJS |
|
|
109
113
|
| `securenow/console-instrumentation` | Console→OTLP bridge; exports `originalConsole`, `restoreConsole()` | CJS |
|
|
@@ -138,7 +142,7 @@ module.exports = {
|
|
|
138
142
|
script: './app.js',
|
|
139
143
|
instances: 4,
|
|
140
144
|
node_args: '-r securenow/register',
|
|
141
|
-
// Reads .securenow/
|
|
145
|
+
// Reads .securenow/runtime.json from the project root.
|
|
142
146
|
}],
|
|
143
147
|
};
|
|
144
148
|
```
|
|
@@ -146,7 +150,7 @@ module.exports = {
|
|
|
146
150
|
**Docker:**
|
|
147
151
|
|
|
148
152
|
```dockerfile
|
|
149
|
-
COPY .securenow/credentials.json ./.securenow/credentials.json
|
|
153
|
+
COPY .securenow/credentials.production.json ./.securenow/credentials.production.json
|
|
150
154
|
CMD ["node", "-r", "securenow/register", "app.js"]
|
|
151
155
|
```
|
|
152
156
|
|
|
@@ -214,7 +218,7 @@ On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-n
|
|
|
214
218
|
}
|
|
215
219
|
```
|
|
216
220
|
|
|
217
|
-
Local development and production do not need `.env.local`; `npx securenow
|
|
221
|
+
Local development and production do not need `.env.local`; `npx securenow app connect` and `npx securenow init` keep `.securenow/runtime.json` filled and gitignored. For production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json` or `.securenow/credentials.production.json`.
|
|
218
222
|
|
|
219
223
|
#### Next.js Body Capture
|
|
220
224
|
|
|
@@ -254,11 +258,11 @@ export const POST = withSecureNow(async (req) => {
|
|
|
254
258
|
#### Next.js with `securenow init`
|
|
255
259
|
|
|
256
260
|
```bash
|
|
257
|
-
npx securenow
|
|
261
|
+
npx securenow app connect
|
|
258
262
|
npx securenow init
|
|
259
263
|
```
|
|
260
264
|
|
|
261
|
-
Auto-detects Next.js, creates `instrumentation.ts`, adds `serverExternalPackages: ['securenow']` plus `outputFileTracingIncludes` when safe, and reuses the app, instance,
|
|
265
|
+
Auto-detects Next.js, creates `instrumentation.ts`, adds `serverExternalPackages: ['securenow']` plus `outputFileTracingIncludes` when safe, and reuses the app, instance, runtime API key, and secure defaults in `.securenow/runtime.json`. If files already exist, it prints an agent-ready prompt with the exact edits to propose.
|
|
262
266
|
|
|
263
267
|
---
|
|
264
268
|
|
|
@@ -270,12 +274,12 @@ Auto-detects Next.js, creates `instrumentation.ts`, adds `serverExternalPackages
|
|
|
270
274
|
export default defineNuxtConfig({
|
|
271
275
|
modules: ['securenow/nuxt'],
|
|
272
276
|
securenow: {
|
|
273
|
-
// optional overrides (defaults come from .securenow/
|
|
277
|
+
// optional overrides (defaults come from .securenow/runtime.json)
|
|
274
278
|
},
|
|
275
279
|
});
|
|
276
280
|
```
|
|
277
281
|
|
|
278
|
-
The Nuxt module auto-configures Nitro externals, runtime config, and a server plugin that sets up OTel tracing + logging + firewall. Local
|
|
282
|
+
The Nuxt module auto-configures Nitro externals, runtime config, and a server plugin that sets up OTel tracing + logging + firewall. Local app identity, runtime API key, and secure defaults come from `.securenow/runtime.json`; production can use tokenless `.securenow/credentials.<env>.json`.
|
|
279
283
|
|
|
280
284
|
---
|
|
281
285
|
|
|
@@ -296,7 +300,7 @@ Instruments document load, fetch, XMLHttpRequest, and user interactions with bro
|
|
|
296
300
|
|
|
297
301
|
## Firewall — Multi-Layer IP Blocking
|
|
298
302
|
|
|
299
|
-
The firewall auto-activates once
|
|
303
|
+
The firewall auto-activates once a runtime API key is resolvable and the app firewall toggle is on. Since **v8.0**, `npx securenow app connect` enables the selected app firewall by default and writes the scoped runtime key to `.securenow/runtime.json`; `securenow api-key set` can still write/rotate the key later. Production should use the tokenless file generated by `securenow credentials runtime --env production`. Runtime resolution order is project `./.securenow/runtime.json` -> legacy project credentials -> project named runtime credentials -> global runtime/legacy/named runtime credentials. Admin auth lives separately in `admin.json`.
|
|
300
304
|
|
|
301
305
|
```
|
|
302
306
|
Layer 4: Cloud/Edge WAF → blocked at CDN (Cloudflare, AWS WAF, GCP Cloud Armor)
|
|
@@ -308,8 +312,8 @@ Layer 1: HTTP Handler → 403 JSON response (always active)
|
|
|
308
312
|
### Activate
|
|
309
313
|
|
|
310
314
|
```bash
|
|
311
|
-
# Zero-config (recommended)
|
|
312
|
-
npx securenow
|
|
315
|
+
# Zero-config runtime (recommended) - writes the key to .securenow/runtime.json
|
|
316
|
+
npx securenow app connect # pick/create app; firewall connects automatically
|
|
313
317
|
# or, if you already have a key:
|
|
314
318
|
npx securenow api-key set snk_live_abc123...
|
|
315
319
|
|
|
@@ -317,6 +321,26 @@ npx securenow api-key set snk_live_abc123...
|
|
|
317
321
|
npx securenow credentials runtime --env production
|
|
318
322
|
```
|
|
319
323
|
|
|
324
|
+
### Scoped Blocklist Entries
|
|
325
|
+
|
|
326
|
+
Manual blocklist entries can target all routes or only matching request scopes.
|
|
327
|
+
Use the dashboard Advanced section, the API, CLI, or MCP with the same fields:
|
|
328
|
+
|
|
329
|
+
```json
|
|
330
|
+
{
|
|
331
|
+
"ip": "203.0.113.42",
|
|
332
|
+
"pathPattern": "/admin*",
|
|
333
|
+
"pathMatchMode": "prefix",
|
|
334
|
+
"method": "ALL",
|
|
335
|
+
"appKey": "optional-app-key",
|
|
336
|
+
"environment": "production",
|
|
337
|
+
"reason": "Admin probing"
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
`pathMatchMode` accepts `prefix`, `exact`, or `regex`. Omit `pathPattern` and
|
|
342
|
+
use `method: "ALL"` for a global IP/CIDR block.
|
|
343
|
+
|
|
320
344
|
### Firewall-Only Mode (No Tracing Overhead)
|
|
321
345
|
|
|
322
346
|
```bash
|
|
@@ -326,7 +350,7 @@ node -r securenow/firewall-only app.js
|
|
|
326
350
|
securenow run --firewall-only app.js
|
|
327
351
|
```
|
|
328
352
|
|
|
329
|
-
Loads only
|
|
353
|
+
Loads only the firewall using SecureNow runtime credentials. No OpenTelemetry, no tracing, no external packages needed.
|
|
330
354
|
|
|
331
355
|
### Programmatic Firewall API
|
|
332
356
|
|
|
@@ -500,7 +524,7 @@ const safe = redactSensitiveData({ username: 'alice', password: 's3cret', token:
|
|
|
500
524
|
|
|
501
525
|
**Auto-redacted fields:** `password`, `passwd`, `pwd`, `secret`, `token`, `api_key`, `apikey`, `access_token`, `auth`, `credentials`, `mysql_pwd`, `stripeToken`, `card`, `cardnumber`, `ccv`, `cvc`, `cvv`, `ssn`, `pin`.
|
|
502
526
|
|
|
503
|
-
Add custom fields via `config.capture.sensitiveFields` in `.securenow/
|
|
527
|
+
Add custom fields via `config.capture.sensitiveFields` in `.securenow/runtime.json`.
|
|
504
528
|
|
|
505
529
|
**CLI equivalent** (for piping, scripts, debugging what a payload looks like post-redaction):
|
|
506
530
|
|
|
@@ -513,13 +537,13 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
513
537
|
|
|
514
538
|
## Credentials Configuration
|
|
515
539
|
|
|
516
|
-
Local development
|
|
540
|
+
Local development uses `.securenow/runtime.json`; legacy `.securenow/credentials.json` is still read. Every setting below lives under `app` or `config`; `npx securenow credentials runtime --env production` creates a tokenless production file with the same structure. Since v7.7.2, the SDK also accepts named runtime files such as `.securenow/credentials.production.json` when the canonical `credentials.json` file is absent. Filename lookup is deterministic and does not read environment variables. Environment-variable fallbacks are not supported.
|
|
517
541
|
|
|
518
542
|
| Credentials path | Purpose |
|
|
519
543
|
|---|---|
|
|
520
544
|
| `app.key` | App routing UUID. The SecureNow ingestion gateway routes telemetry by this key |
|
|
521
545
|
| `app.name` | Human-readable app label |
|
|
522
|
-
| `apiKey` | Scoped
|
|
546
|
+
| `apiKey` | Scoped runtime API key (`snk_live_...`) |
|
|
523
547
|
| `config.otel.endpoint` | Optional OTLP base endpoint override |
|
|
524
548
|
| `config.otel.tracesEndpoint` | Optional full traces endpoint |
|
|
525
549
|
| `config.otel.logsEndpoint` | Optional full logs endpoint |
|
|
@@ -565,7 +589,7 @@ npm install securenow@latest
|
|
|
565
589
|
npx securenow login
|
|
566
590
|
```
|
|
567
591
|
|
|
568
|
-
No `.env` is needed. `npx securenow
|
|
592
|
+
No `.env` is needed. `npx securenow app connect` writes app identity, runtime API key, and secure defaults to `.securenow/runtime.json`; the SDK uses the default SecureNow ingestion gateway and the gateway routes by `app.key` while authenticating with the runtime API key. `npx securenow init` makes sure the file has explanations and is gitignored without ignoring the whole `.securenow/` directory.
|
|
569
593
|
|
|
570
594
|
Update `package.json`:
|
|
571
595
|
```json
|
|
@@ -578,10 +602,10 @@ No code changes to the application needed.
|
|
|
578
602
|
|
|
579
603
|
```bash
|
|
580
604
|
npm install securenow@latest
|
|
581
|
-
npx securenow
|
|
605
|
+
npx securenow app connect # pick/create app; runtime API key is minted automatically
|
|
582
606
|
```
|
|
583
607
|
|
|
584
|
-
`securenow
|
|
608
|
+
`securenow app connect` enables the selected app's firewall toggle and writes app/runtime config plus the runtime API key to `.securenow/runtime.json` (gitignored via credential-file patterns, not a whole-directory `.securenow/` ignore). Traces, logs, request body capture, multipart metadata capture, and firewall enforcement are enabled by default. Then run `npx securenow init`; it creates `instrumentation.ts`, patches `next.config.*` when safe, or prints exact Codex/Claude merge instructions for existing files.
|
|
585
609
|
|
|
586
610
|
### Enable Firewall With Zero Tracing Overhead
|
|
587
611
|
|
|
@@ -591,7 +615,7 @@ For apps that only need IP blocking:
|
|
|
591
615
|
node -r securenow/firewall-only app.js
|
|
592
616
|
```
|
|
593
617
|
|
|
594
|
-
Make sure an API key is resolvable by running `npx securenow
|
|
618
|
+
Make sure an API key is resolvable by running `npx securenow app connect` first. If you already have a key, `securenow api-key set snk_live_...` writes the runtime credentials file. For production, run `npx securenow credentials runtime --env production` and mount/copy it as `.securenow/credentials.json` or `.securenow/credentials.production.json`.
|
|
595
619
|
|
|
596
620
|
### Production Hardened Configuration
|
|
597
621
|
|
package/SKILL-CLI.md
CHANGED
|
@@ -24,24 +24,27 @@ codex mcp add securenow -- npx securenow mcp
|
|
|
24
24
|
npx -p securenow securenow-mcp
|
|
25
25
|
```
|
|
26
26
|
|
|
27
|
-
The MCP server
|
|
27
|
+
The MCP server reads admin/control-plane auth from `.securenow/admin.json` and SDK runtime app credentials from `.securenow/runtime.json`, with legacy `.securenow/credentials.json` still supported. Admin/global tools use admin auth; runtime-scoped read tools can use the runtime API key where its scopes allow it. Write tools require `confirm:true` plus a reason.
|
|
28
28
|
|
|
29
29
|
### Authenticate
|
|
30
30
|
|
|
31
31
|
```bash
|
|
32
|
-
securenow login #
|
|
33
|
-
securenow login
|
|
34
|
-
securenow
|
|
35
|
-
securenow
|
|
36
|
-
|
|
32
|
+
securenow login # friendly flow: admin auth + app runtime connection
|
|
33
|
+
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
34
|
+
securenow app connect # app/runtime SDK connection only
|
|
35
|
+
securenow admin login --token <JWT> # headless / CI admin auth
|
|
36
|
+
securenow whoami # verify both admin auth and runtime app status
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Two-lane credentials (v8.0+):** admin/control-plane auth lives in `.securenow/admin.json`; SDK runtime app config and the runtime API key live in `.securenow/runtime.json`. `securenow login` can run both lanes for onboarding, but `securenow admin login` never replaces runtime app config and `securenow app connect` never replaces admin auth. Legacy combined `.securenow/credentials.json` files are still read.
|
|
37
40
|
|
|
38
|
-
**Zero-config flow
|
|
41
|
+
**Zero-config runtime flow:** the browser step lets the user pick (or create) an app. The CLI stores the app's **key (UUID)** and **name** in `.securenow/runtime.json`. The SDK sends traces/logs to the default SecureNow ingestion gateway, which routes by app key, so no env vars or per-instance collector URLs are required for local dev or production.
|
|
39
42
|
|
|
40
|
-
**Default-on security (v7.5.1+):** after picking or creating the app, `securenow
|
|
43
|
+
**Default-on security (v7.5.1+):** after picking or creating the app, `securenow app connect` turns on that app's firewall toggle, mints an API key with `firewall:read + blocklist:read + allowlist:read` scopes, and writes it into `.securenow/runtime.json`. Traces, logs, POST body capture, multipart metadata capture, and the firewall are enabled by default. No `SECURENOW_API_KEY` env var is needed. To add or rotate a key later without re-running app connect, use `securenow api-key set snk_live_...` (see [API Key Management](#api-key-management) below).
|
|
41
44
|
|
|
42
|
-
|
|
45
|
+
Runtime credentials resolve in order: project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Runtime config is credentials-json based; environment-variable fallbacks are not supported.
|
|
43
46
|
|
|
44
|
-
The **firewall API key** should live in
|
|
47
|
+
The **firewall API key** should live in runtime credentials as `apiKey`.
|
|
45
48
|
|
|
46
49
|
For CI / Docker / production, use `securenow credentials runtime --env production` to generate a tokenless runtime file, then mount/copy it as `.securenow/credentials.json`. Since v7.7.2, mounting the generated `.securenow/credentials.production.json` filename directly also works when `credentials.json` is absent.
|
|
47
50
|
|
|
@@ -62,11 +65,11 @@ node -r securenow/register src/index.js
|
|
|
62
65
|
For Next.js, run the interactive scaffolding:
|
|
63
66
|
|
|
64
67
|
```bash
|
|
65
|
-
securenow login
|
|
66
|
-
securenow init
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
This auto-detects your framework, creates the necessary `instrumentation.ts` and `next.config.js` changes, and reuses the app, instance, and
|
|
68
|
+
securenow login
|
|
69
|
+
securenow init
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This auto-detects your framework, creates the necessary `instrumentation.ts` and `next.config.js` changes, and reuses the app, instance, and runtime API key written by login or `app connect` to `.securenow/runtime.json`.
|
|
70
73
|
|
|
71
74
|
### Install This Skill in Cursor
|
|
72
75
|
|
|
@@ -76,16 +79,19 @@ Save this file as `.cursor/skills/securenow-cli/SKILL.md` in your project. Your
|
|
|
76
79
|
|
|
77
80
|
Config lives in `~/.securenow/` (global) and optionally `.securenow/` (per-project):
|
|
78
81
|
|
|
79
|
-
| File | Content |
|
|
80
|
-
|------|---------|
|
|
81
|
-
| `~/.securenow/config.json` | `apiUrl`, `appUrl`, `defaultApp`, `output` |
|
|
82
|
-
| `~/.securenow/
|
|
83
|
-
|
|
|
82
|
+
| File | Content |
|
|
83
|
+
|------|---------|
|
|
84
|
+
| `~/.securenow/config.json` | `apiUrl`, `appUrl`, `defaultApp`, `output` |
|
|
85
|
+
| `~/.securenow/admin.json` | `token`, `email`, `expiresAt` for global admin/control-plane CLI and MCP auth |
|
|
86
|
+
| `~/.securenow/runtime.json` | `apiKey`, `app`, `config` for global SDK runtime |
|
|
87
|
+
| `.securenow/admin.json` | `token`, `email`, `expiresAt` for project-local admin/control-plane CLI and MCP auth |
|
|
88
|
+
| `.securenow/runtime.json` | `apiKey`, `app`, `config`, `_securenow.explanations` for project-local SDK runtime |
|
|
89
|
+
| `.securenow/credentials.json` | Legacy combined credentials; still read for backward compatibility |
|
|
84
90
|
| `.securenow/credentials.<environment>.json` | Tokenless runtime credentials generated by `securenow credentials runtime --env <environment>`; read in a fixed order, not selected from env vars |
|
|
85
91
|
|
|
86
|
-
**Credential resolution order:** `.securenow/
|
|
92
|
+
**Credential resolution order:** runtime config resolves from project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Environment-variable fallbacks are not supported.
|
|
87
93
|
|
|
88
|
-
**
|
|
94
|
+
**Runtime API key resolution (v8.0+):** project `.securenow/runtime.json` -> legacy project credentials -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global runtime credentials -> legacy global credentials -> global named runtime credentials. Use `securenow app connect` for runtime setup or `securenow api-key set` to rotate a key without touching admin auth or env vars.
|
|
89
95
|
|
|
90
96
|
```bash
|
|
91
97
|
securenow config set apiUrl https://api.securenow.ai
|
|
@@ -107,7 +113,7 @@ Legacy CLI overrides still exist for operator automation, but runtime SDK config
|
|
|
107
113
|
| `--force` | `-f` | Skip confirmations |
|
|
108
114
|
| `--yes` | `-y` | Auto-confirm prompts |
|
|
109
115
|
|
|
110
|
-
|
|
116
|
+
SecureNow-specific environment overrides are not supported; use `.securenow/runtime.json`, `.securenow/admin.json`, or `securenow config set`.
|
|
111
117
|
|
|
112
118
|
---
|
|
113
119
|
|
|
@@ -123,17 +129,18 @@ securenow run --firewall-only app.js # preload firewall only (no tracing
|
|
|
123
129
|
securenow src/index.js # shorthand — auto-detected as "run"
|
|
124
130
|
```
|
|
125
131
|
|
|
126
|
-
Spawns `node --require securenow/register [--import otel/hook.mjs] <script>`. ESM detection uses nearest `package.json` `"type"` field or `.mjs`/`.cjs` extension. With `--firewall-only`, uses `securenow/firewall-only` instead (
|
|
132
|
+
Spawns `node --require securenow/register [--import otel/hook.mjs] <script>`. ESM detection uses nearest `package.json` `"type"` field or `.mjs`/`.cjs` extension. With `--firewall-only`, uses `securenow/firewall-only` instead (credentials-file firewall, no OpenTelemetry).
|
|
127
133
|
|
|
128
134
|
### Authentication
|
|
129
135
|
|
|
130
136
|
```bash
|
|
131
|
-
securenow login #
|
|
132
|
-
securenow login
|
|
133
|
-
securenow login --
|
|
134
|
-
securenow
|
|
135
|
-
securenow logout
|
|
136
|
-
securenow
|
|
137
|
+
securenow login # friendly flow: admin auth + app runtime connection
|
|
138
|
+
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
139
|
+
securenow admin login --token <JWT> # headless / CI admin auth
|
|
140
|
+
securenow app connect # app/runtime SDK connection only
|
|
141
|
+
securenow logout # clear admin auth; runtime app config remains
|
|
142
|
+
securenow logout --global # clear global admin auth only
|
|
143
|
+
securenow whoami # show admin auth and runtime app status separately
|
|
137
144
|
```
|
|
138
145
|
|
|
139
146
|
### Applications
|
|
@@ -151,10 +158,10 @@ securenow apps scan [--yes] # scan all app domains for new subd
|
|
|
151
158
|
|
|
152
159
|
### API Key Management
|
|
153
160
|
|
|
154
|
-
Manage the
|
|
161
|
+
Manage the runtime API key stored in runtime credentials. Since v8.0 the app runtime flow writes app-scoped `snk_live_...` keys to `.securenow/runtime.json` by default, so no env var is required for local dev.
|
|
155
162
|
|
|
156
163
|
```bash
|
|
157
|
-
securenow api-key create --name "CLI
|
|
164
|
+
securenow api-key create --name "CLI runtime" # mint + save a runtime API key with your logged-in session
|
|
158
165
|
securenow api-key set snk_live_xxxxxxxxxx # save to project ./.securenow/ (default)
|
|
159
166
|
securenow api-key set snk_live_xxx --global # save to ~/.securenow/ instead
|
|
160
167
|
securenow api-key show # print the masked current key + its source
|
|
@@ -163,7 +170,7 @@ securenow api-key clear --global # same, but from the global file
|
|
|
163
170
|
securenow credentials runtime --env production # write .securenow/credentials.production.json for production secret-file deploys
|
|
164
171
|
```
|
|
165
172
|
|
|
166
|
-
The key must start with `snk_live_`. `securenow
|
|
173
|
+
The key must start with `snk_live_`. `securenow app connect` writes the key automatically; use `api-key create` when you have admin auth but no runtime key yet, or `api-key set` when you already have a key from the dashboard.
|
|
167
174
|
|
|
168
175
|
### Init — Project Setup
|
|
169
176
|
|
|
@@ -172,12 +179,12 @@ securenow init [--env local] [--key <API_KEY>]
|
|
|
172
179
|
```
|
|
173
180
|
|
|
174
181
|
Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
|
|
175
|
-
- **Credentials**: ensures `.securenow/
|
|
182
|
+
- **Credentials**: ensures `.securenow/runtime.json` exists, has secure defaults/explanations, and local credential JSON files are gitignored without ignoring the whole `.securenow/` directory
|
|
176
183
|
- **Next.js**: creates `instrumentation.ts/js` with `securenow/nextjs` + `securenow/nextjs-auto-capture`, and adds `serverExternalPackages: ['securenow']` plus `outputFileTracingIncludes` when the config can be patched safely
|
|
177
184
|
- **Existing Next.js files**: prints a Codex/Claude-ready merge prompt when instrumentation or config already exists or is too custom to safely patch
|
|
178
185
|
- **Nuxt**: tells you to add `securenow/nuxt` to modules
|
|
179
186
|
- **Node/Express/etc.**: suggests adding `-r securenow/register` to start script
|
|
180
|
-
- Reuses `.securenow/
|
|
187
|
+
- Reuses `.securenow/runtime.json` written by login/app connect; production should mount/copy the tokenless runtime file generated by `securenow credentials runtime --env production`
|
|
181
188
|
|
|
182
189
|
### Dashboard & Status
|
|
183
190
|
|
|
@@ -264,9 +271,10 @@ MCP parity for noisy alert-rule reviews:
|
|
|
264
271
|
- `securenow_alert_rule_candidate_test` dry-runs a full candidate SQL query without saving it.
|
|
265
272
|
- `securenow_alert_rule_test_result` polls the dry-run.
|
|
266
273
|
- `securenow_alert_rule_query_update` updates the shared public query mapping behind a system rule for all customer copies. It is admin-only, requires `confirm:true`, `applyGlobally:true`, `reason`, and SQL that keeps `__USER_APP_KEYS__` tenant scoping.
|
|
274
|
+
- `securenow_alert_rule_instant_update` patches Instant rule conditions/config with stale-write guards. Fetch the rule first, pass `expectedRuleVersion` plus `expectedCurrentInstantHash`, use operations such as `remove_condition` / `add_condition` / `update_condition`, and set `applyGlobally:true` for system rules. The API runs seeded before/after checks and returns benign samples removed plus attack samples still matching. If global tuning is denied, it returns a structured admin handoff with the exact patch and missing permission.
|
|
267
275
|
- `securenow_alert_rule_exclusion_add` remains the last-resort customer-specific path; it supports restrictive conditions plus `matchMode` and should not be used to hide a generic system-rule bug.
|
|
268
276
|
|
|
269
|
-
For system-rule tuning, dry-run the candidate SQL first,
|
|
277
|
+
For system-rule tuning, dry-run the candidate SQL first for scheduled rules, or use `dryRun:true` on `securenow_alert_rule_instant_update` for Instant rules. Save only when the guard preserves attack detection. Good guards add exact exploit tokens, dangerous schemes, matched subdetectors, sensitive path/status evidence, malicious user agents, or repeat thresholds; bad guards simply suppress a noisy path.
|
|
270
278
|
|
|
271
279
|
---
|
|
272
280
|
|
|
@@ -305,7 +313,7 @@ securenow firewall status --app <key> --env production # app/env toggle, sync
|
|
|
305
313
|
securenow firewall test-ip <ip> --app <key> --env local # check if IP would be blocked
|
|
306
314
|
```
|
|
307
315
|
|
|
308
|
-
**Zero-config setup
|
|
316
|
+
**Zero-config setup:** running `securenow app connect` enables the selected app's firewall toggle, auto-mints an API key (scoped `firewall:read + blocklist:read + allowlist:read`), and writes it to `.securenow/runtime.json` after the app is selected. No `SECURENOW_API_KEY` env var needed. If the user already has a key, `securenow api-key set snk_live_...` achieves the same thing. See [the landing firewall page](https://securenow.ai/firewall) for an overview.
|
|
309
317
|
|
|
310
318
|
### Blocklist — Block Malicious IPs
|
|
311
319
|
|
|
@@ -313,12 +321,17 @@ securenow firewall test-ip <ip> --app <key> --env local # check if IP would be
|
|
|
313
321
|
securenow blocklist # list blocked IPs
|
|
314
322
|
securenow blocklist list
|
|
315
323
|
securenow blocklist add <ip> --app <key> --env production --reason "Brute force"
|
|
324
|
+
securenow blocklist add <ip> --route /admin* --mode prefix --method ALL --reason "Admin probing"
|
|
316
325
|
securenow blocklist unblock <id> --reason "False alarm after review"
|
|
317
326
|
securenow blocklist remove <id> # compatibility alias for unblock
|
|
318
327
|
securenow blocklist list --status removed # audit retained unblocks
|
|
319
328
|
securenow blocklist stats # block counts, top reasons
|
|
320
329
|
```
|
|
321
330
|
|
|
331
|
+
Scoped blocks use the same model as rate limits: `--route`/`--path`/`--pattern`
|
|
332
|
+
sets `pathPattern`, `--mode`/`--path-mode` chooses `prefix`, `exact`, or
|
|
333
|
+
`regex`, and `--method` limits enforcement to one HTTP method or `ALL`.
|
|
334
|
+
|
|
322
335
|
Unblock stops firewall enforcement but preserves the block report, history, and
|
|
323
336
|
unblock audit fields. Reblocking the same IP later creates a fresh active block
|
|
324
337
|
without erasing the previous investigation trail.
|
|
@@ -368,7 +381,13 @@ supporting evidence, not the primary automation score.
|
|
|
368
381
|
|
|
369
382
|
### Allowlist — Restrict to Known IPs
|
|
370
383
|
|
|
371
|
-
|
|
384
|
+
Dangerous production mode: IP Allowlist is deny-by-default. Once any active
|
|
385
|
+
allowlist entry exists for an app/environment, only listed IPs can reach it and
|
|
386
|
+
all other IPs are blocked. Do not use allowlist to mark an IP trusted, suppress
|
|
387
|
+
false positives, or clean up investigations. Use `securenow trusted add` for
|
|
388
|
+
known-safe monitors, office/VPN traffic, or trusted bypass cases.
|
|
389
|
+
|
|
390
|
+
```bash
|
|
372
391
|
securenow allowlist # list allowed IPs
|
|
373
392
|
securenow allowlist list
|
|
374
393
|
securenow allowlist add <ip> --app <key> --env local --label "Office" --reason "Corporate VPN"
|
|
@@ -376,10 +395,13 @@ securenow allowlist remove <id>
|
|
|
376
395
|
securenow allowlist stats
|
|
377
396
|
```
|
|
378
397
|
|
|
379
|
-
### Trusted
|
|
398
|
+
### Trusted IPs
|
|
380
399
|
|
|
381
|
-
|
|
382
|
-
|
|
400
|
+
Trusted IPs are the safe bypass/suppression mechanism for known infrastructure
|
|
401
|
+
and do not enable deny-by-default allowlist mode.
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
securenow trusted # list trusted IPs
|
|
383
405
|
securenow trusted list
|
|
384
406
|
securenow trusted add <ip> [--label "CloudFlare edge"]
|
|
385
407
|
securenow trusted remove <id>
|
|
@@ -473,7 +495,7 @@ securenow test-span
|
|
|
473
495
|
securenow test-span "ci.smoke-test" # custom span name
|
|
474
496
|
```
|
|
475
497
|
|
|
476
|
-
Both commands use the default SecureNow ingestion gateway plus optional advanced `config.otel.*` overrides from `.securenow/
|
|
498
|
+
Both commands use the default SecureNow ingestion gateway plus optional advanced `config.otel.*` overrides from `.securenow/runtime.json` or legacy runtime credentials, and return non-zero on HTTP errors so CI/cron can detect failures.
|
|
477
499
|
|
|
478
500
|
### Utilities — Redaction, CIDR, Diagnostics
|
|
479
501
|
|
|
@@ -581,10 +603,10 @@ All commands support `--json` for structured output. When piping to other tools
|
|
|
581
603
|
|
|
582
604
|
| Exit code / Error | Meaning | Recovery |
|
|
583
605
|
|------------------|---------|----------|
|
|
584
|
-
| `Session expired` | JWT expired | `securenow login` (or `login --global` for shared
|
|
585
|
-
| `Not logged in` | No token found | `securenow login
|
|
606
|
+
| `Session expired` | Admin JWT expired | `securenow admin login` (or `admin login --global` for shared admin auth) |
|
|
607
|
+
| `Not logged in` | No admin token found | `securenow admin login`; runtime `.securenow/runtime.json` is unrelated |
|
|
586
608
|
| `Access denied (403)` | Insufficient plan or permissions | Upgrade plan or check user role |
|
|
587
609
|
| `Cannot connect` | API unreachable | Check `securenow config get apiUrl` or network |
|
|
588
610
|
| `Unknown command` | Typo or unrecognized command | `securenow help` |
|
|
589
611
|
|
|
590
|
-
|
|
612
|
+
SecureNow-specific environment overrides are intentionally unsupported for troubleshooting; use explicit CLI config files and normal terminal logs.
|