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/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 (v7.5+):** `npx securenow mcp` starts a local stdio MCP server for Codex, Claude, and other MCP clients. It reuses the same `.securenow/credentials.json` file as the CLI/SDK and exposes SecureNow tools, bundled docs resources, and setup prompts to agents. 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` when evidence is clear.
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.5.1` or newer. Start authentication with `npx securenow login`; do not manually open auth URLs, because the CLI generates the callback/state values. The login flow lets the user pick or create an app, enables the app firewall by default, writes `.securenow/credentials.json`, and `init` scaffolds the framework integration.
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 v7.5.1, the browser login flow connects the firewall automatically after
60
- the user picks or creates an app. The firewall key lives in your credentials
61
- file — no env var required:
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 login # pick/create app; firewall key is minted automatically
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/credentials.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`.
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/credentials.json`. The SDK polls `/firewall/sync` with ETag/304, so
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: dotenv + firewall only, no tracing | Preload (`-r`) |
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/credentials.json from the project root.
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 login` and `npx securenow init` keep `.securenow/credentials.json` filled and gitignored. For production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json`.
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 login
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, firewall key, and secure defaults in `.securenow/credentials.json`. If files already exist, it prints an agent-ready prompt with the exact edits to propose.
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/credentials.json)
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 and production app identity, firewall key, and secure defaults come from `.securenow/credentials.json`.
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 an API key is resolvable and the app firewall toggle is on. Since **v7.5.1**, `npx securenow login` enables the selected app firewall by default and writes the scoped key to `.securenow/credentials.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`. Resolution order: project `./.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `~/.securenow/credentials.json` -> global named runtime credentials in the same fixed order. Runtime config is credentials-json based; legacy env fallback is disabled unless `SECURENOW_ENABLE_LEGACY_ENV=1` is explicitly set for an old deployment.
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) — writes the key to .securenow/credentials.json
312
- npx securenow login # pick/create app; firewall connects automatically
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 dotenv + firewall. No OpenTelemetry, no tracing, no external packages needed.
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/credentials.json`.
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 and production use `.securenow/credentials.json`. 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. Legacy env fallback is disabled unless `SECURENOW_ENABLE_LEGACY_ENV=1` is explicitly set.
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 firewall key (`snk_live_...`) |
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 login` writes app identity, firewall key, and secure defaults to `.securenow/credentials.json`; the SDK uses the default SecureNow ingestion gateway and the gateway routes by `app.key`. `npx securenow init` makes sure the file has explanations and is gitignored without ignoring the whole `.securenow/` directory.
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 login # pick/create app; firewall key is minted automatically
605
+ npx securenow app connect # pick/create app; runtime API key is minted automatically
582
606
  ```
583
607
 
584
- `securenow login` enables the selected app's firewall toggle and writes session, app, and firewall key to `.securenow/credentials.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.
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 login` first. If you already have a key, `securenow api-key set snk_live_...` writes the creds file. For production, run `npx securenow credentials runtime --env production` and mount/copy it as `.securenow/credentials.json`.
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 reuses `.securenow/credentials.json` and exposes apps, traces, logs, firewall, IP intelligence, forensics, notifications, remediation tools, alert-rule review/tuning tools, bundled docs resources, and setup prompts. Write tools require `confirm:true` plus a reason.
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 # opens browser OAuth + app picker; writes ./.securenow/credentials.json (project-local by default)
33
- securenow login --global # save to ~/.securenow/ instead (shared across projects)
34
- securenow login --token <JWT> # headless / CI login (get token from dashboard Settings)
35
- securenow whoami # verify session (shows email, app, auth source)
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 (v7+):** the browser step lets the user pick (or create) an app. The CLI stores the app's **key (UUID)** and **name** in `.securenow/credentials.json`. The SDK sends traces/logs to the default SecureNow ingestion gateway, which routes by app key **no env vars or per-instance collector URLs required for local dev or production**.
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 login` turns on that app's firewall toggle, mints an API key with `firewall:read + blocklist:read + allowlist:read` scopes, and writes it into `.securenow/credentials.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 login, use `securenow api-key set snk_live_...` (see [API Key Management](#api-key-management) below).
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
- Credentials resolve in order: project `.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `~/.securenow/credentials.json` -> global named runtime credentials in the same fixed order. Runtime config is credentials-json based; legacy env fallbacks are disabled unless `SECURENOW_ENABLE_LEGACY_ENV=1` is set and never choose the credentials filename.
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 the same credentials file as `apiKey`.
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 firewall key written by login to `.securenow/credentials.json`.
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/credentials.json` | `token`, `email`, `expiresAt`, `apiKey`, `app`, `config` (global, use `login --global`) |
83
- | `.securenow/credentials.json` | `token`, `email`, `expiresAt`, `apiKey`, `app`, `config`, `_securenow.explanations` (project-local default) |
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/credentials.json` (project) -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> `~/.securenow/credentials.json` (global) -> global named runtime credentials in the same fixed order. Legacy env fallbacks are disabled unless `SECURENOW_ENABLE_LEGACY_ENV=1` is set.
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
- **Firewall API key resolution (v7.5.1+):** project `.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `~/.securenow/credentials.json` -> global named runtime credentials in the same fixed order. Use `securenow login` for default setup or `securenow api-key set` to rotate a key without touching env vars.
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
- Debug mode: `SECURENOW_DEBUG=1 securenow <cmd>` prints stack traces on errors.
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 (dotenv + firewall, no OpenTelemetry).
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 # browser-based OAuth (stores in project ./.securenow/)
132
- securenow login --token <JWT> # headless / CI login
133
- securenow login --global # save credentials to ~/.securenow/ instead
134
- securenow logout # clear active credentials (local if present, else global)
135
- securenow logout --global # clear global credentials only
136
- securenow whoami # show email, user ID, API URL, auth source, expiry, default app
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 firewall API key stored in the credentials file. Since v7.5.1 the login flow writes `snk_live_...` keys to `.securenow/credentials.json` by default, so no env var is required for local dev.
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 firewall" # mint + save a firewall key with your logged-in session
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 login` with firewall enabled writes the key automatically; use `api-key create` when you have an account session but no runtime key yet, or `api-key set` when you already have a key from the dashboard.
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/credentials.json` exists, has secure defaults/explanations, and local credential JSON files are gitignored without ignoring the whole `.securenow/` directory
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/credentials.json` written by login; production should mount/copy the tokenless runtime file generated by `securenow credentials runtime --env production`
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, then save with `tune-query`/`securenow_alert_rule_query_update` 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.
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 (v7.5.1+):** running `securenow login` enables the selected app's firewall toggle, auto-mints an API key (scoped `firewall:read + blocklist:read + allowlist:read`), and writes it to the credentials file 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.
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
- ```bash
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 Proxies
398
+ ### Trusted IPs
380
399
 
381
- ```bash
382
- securenow trusted # list trusted IPs
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/credentials.json`, and return non-zero on HTTP errors so CI/cron can detect failures.
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 credentials) |
585
- | `Not logged in` | No token found | `securenow login` or mount/copy the right `.securenow/credentials.json` |
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
- Set `SECURENOW_DEBUG=1` for full stack traces on any error.
612
+ SecureNow-specific environment overrides are intentionally unsupported for troubleshooting; use explicit CLI config files and normal terminal logs.