securenow 7.5.1 → 7.6.1

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.
Files changed (50) hide show
  1. package/CONSUMING-APPS-GUIDE.md +2 -0
  2. package/NPM_README.md +201 -237
  3. package/README.md +73 -26
  4. package/SKILL-API.md +205 -205
  5. package/SKILL-CLI.md +71 -64
  6. package/app-config.js +479 -83
  7. package/cli/apiKey.js +1 -1
  8. package/cli/apps.js +1 -1
  9. package/cli/config.js +31 -12
  10. package/cli/credentials.js +88 -0
  11. package/cli/diagnostics.js +68 -104
  12. package/cli/firewall.js +29 -14
  13. package/cli/init.js +211 -212
  14. package/cli/monitor.js +107 -43
  15. package/cli/security.js +24 -12
  16. package/cli/utils.js +2 -1
  17. package/cli.js +72 -40
  18. package/console-instrumentation.js +1 -1
  19. package/docs/ENVIRONMENT-VARIABLES.md +137 -863
  20. package/docs/ENVIRONMENTS.md +60 -0
  21. package/docs/EXPRESS-SETUP-GUIDE.md +3 -0
  22. package/docs/FIREWALL-GUIDE.md +3 -0
  23. package/docs/INDEX.md +6 -8
  24. package/docs/LOGGING-GUIDE.md +3 -0
  25. package/docs/MCP-GUIDE.md +8 -0
  26. package/docs/NEXTJS-GUIDE.md +3 -0
  27. package/docs/NEXTJS-QUICKSTART.md +22 -16
  28. package/docs/NUXT-GUIDE.md +3 -0
  29. package/docs/QUICKSTART-BODY-CAPTURE.md +3 -0
  30. package/docs/REQUEST-BODY-CAPTURE.md +3 -0
  31. package/firewall-cloud.js +10 -10
  32. package/firewall-only.js +25 -23
  33. package/firewall.js +47 -29
  34. package/free-trial-banner.js +1 -1
  35. package/mcp/catalog.js +104 -17
  36. package/nextjs-auto-capture.d.ts +7 -4
  37. package/nextjs-auto-capture.js +7 -7
  38. package/nextjs-middleware.js +4 -3
  39. package/nextjs-wrapper.js +6 -6
  40. package/nextjs.d.ts +36 -25
  41. package/nextjs.js +48 -55
  42. package/nuxt-server-plugin.mjs +35 -51
  43. package/nuxt.d.ts +29 -23
  44. package/package.json +1 -1
  45. package/postinstall.js +27 -61
  46. package/register.d.ts +19 -33
  47. package/register.js +8 -8
  48. package/resolve-ip.js +4 -5
  49. package/tracing.d.ts +21 -19
  50. package/tracing.js +34 -42
package/NPM_README.md CHANGED
@@ -9,10 +9,9 @@ OpenTelemetry instrumentation library for Node.js, Next.js, and Nuxt application
9
9
  - Built-in sensitive data redaction
10
10
  - Request body capture for debugging
11
11
  - Multi-layer firewall -- auto-blocks IPs from your SecureNow blocklist
12
- - `withSecureNow()` config wrapper for Next.js -- eliminates manual `serverExternalPackages`
13
- - `securenow init` CLI scaffolds instrumentation files for any framework
12
+ - `securenow init` scaffolds Next.js instrumentation and safe `serverExternalPackages`
14
13
  - `securenow/firewall-only` entry point for firewall without tracing overhead
15
- - Fully configurable via environment variables
14
+ - Local and production configuration via `.securenow/credentials.json`
16
15
  - Single `-r securenow/register` flag -- works for both CJS and ESM apps
17
16
  - Native Nuxt 3 module (`securenow/nuxt`)
18
17
 
@@ -68,35 +67,26 @@ npx securenow login
68
67
 
69
68
  During the browser step, the dashboard enables the selected app's firewall toggle, mints an API key (scoped `firewall:read + blocklist:read + allowlist:read`), and the CLI writes it into `.securenow/credentials.json`. Traces, logs, POST body capture, multipart metadata capture, and firewall protection are enabled by default. No env vars, no copy-pasting keys.
70
69
 
71
- For framework scaffolding (Next.js `instrumentation.ts`, etc.) use:
70
+ For framework scaffolding (Next.js `instrumentation.ts`, `next.config.*`, etc.) use:
72
71
 
73
72
  ```bash
74
- npx securenow init --key snk_live_abc123... # --key is optional now that login handles it
73
+ npx securenow init
74
+ # Optional, when you already have a key and did not use browser login:
75
+ npx securenow init --key snk_live_abc123...
75
76
  ```
76
77
 
77
78
  This detects your framework and:
78
- - **Next.js**: Creates `instrumentation.ts`, suggests `withSecureNow()` for `next.config.js`
79
+ - **Credentials**: Ensures `.securenow/credentials.json` has secure defaults and explanations
80
+ - **Next.js**: Creates `instrumentation.ts`, adds `serverExternalPackages: ['securenow']` when safe, or prints a Codex/Claude-ready merge prompt for existing files
79
81
  - **Nuxt 3**: Suggests adding `securenow/nuxt` to modules
80
82
  - **Express / Node.js**: Shows how to add `-r securenow/register` to your start script
81
- - **All**: Writes `SECURENOW_API_KEY` to `.env.local` when `--key` is provided (not needed if `login` already wrote it to `.securenow/credentials.json`)
83
+ - **All**: Stores `--key` in `.securenow/credentials.json`; no local `.env` file is needed
82
84
 
83
85
  ### 2. Manual Setup
84
86
 
85
- #### Set Environment Variables
86
-
87
- ```bash
88
- # Required: Your application identifier
89
- export SECURENOW_APPID=my-app
87
+ #### Configure Locally
90
88
 
91
- # Required: Your OTLP collector endpoint
92
- export SECURENOW_INSTANCE=http://your-otlp-collector:4318
93
-
94
- # Optional: Enable logging
95
- export SECURENOW_LOGGING_ENABLED=1
96
-
97
- # Optional: Enable the firewall (set your API key)
98
- export SECURENOW_API_KEY=snk_live_abc123...
99
- ```
89
+ Run `npx securenow login` to write `.securenow/credentials.json`. The SDK reads app identity, collector URL, firewall key, logging/body-capture defaults, and firewall defaults from that file at boot. Production uses the same file shape via `npx securenow credentials runtime --env production`.
100
90
 
101
91
  #### Run Your Application
102
92
 
@@ -161,8 +151,8 @@ npx securenow login
161
151
  # Or use a token for CI/headless environments
162
152
  npx securenow login --token <YOUR_JWT>
163
153
 
164
- # Log in for this project only (per-project credentials)
165
- npx securenow login --local
154
+ # Save to ~/.securenow/ instead of this project
155
+ npx securenow login --global
166
156
 
167
157
  # Check who you're logged in as (shows auth source)
168
158
  npx securenow whoami
@@ -179,11 +169,11 @@ npx securenow api-key clear # remove just the key
179
169
  # Auto-detect framework and scaffold instrumentation files
180
170
  npx securenow init
181
171
 
182
- # Pass your API key to auto-write it to .env.local
172
+ # Pass your API key to store it in .securenow/credentials.json
183
173
  npx securenow init --key snk_live_abc123...
184
174
  ```
185
175
 
186
- For Next.js projects, `init` creates `instrumentation.ts` (or `.js` if no TypeScript) and tells you how to update `next.config.js` with `withSecureNow()`. For Nuxt, it suggests adding `securenow/nuxt` to your modules. For Express/Node, it shows the `-r securenow/register` flag.
176
+ For Next.js projects, `init` creates `instrumentation.ts` (or `.js` if no TypeScript), adds `serverExternalPackages: ['securenow']` when safe, and prints exact merge instructions for Codex/Claude when existing files need judgment. For Nuxt, it suggests adding `securenow/nuxt` to your modules. For Express/Node, it shows the `-r securenow/register` flag.
187
177
 
188
178
  ### MCP for Codex and Claude
189
179
 
@@ -394,7 +384,7 @@ npx securenow redact @request.json --fields internal_id,sessionHash
394
384
  npx securenow cidr match 10.0.0.5 10.0.0.0/8,192.168.1.0/24 # exit 0 = hit, 2 = miss
395
385
  npx securenow cidr parse 10.0.0.0/24 # network, broadcast, mask, size
396
386
 
397
- # Show resolved config (service name, endpoints, env vars, firewall layers)
387
+ # Show resolved config (service name, endpoints, credentials, firewall layers)
398
388
  npx securenow env # human-readable
399
389
  npx securenow env --json # pipe to jq
400
390
 
@@ -423,10 +413,10 @@ Config files are stored in `~/.securenow/` (global) or `.securenow/` in the proj
423
413
  | File | Description |
424
414
  |------|-------------|
425
415
  | `~/.securenow/config.json` | API URL, default app, output format |
426
- | `~/.securenow/credentials.json` | Auth token global (file permissions: 0600) |
427
- | `.securenow/credentials.json` | Auth token project-local (use `login --local`) |
416
+ | `~/.securenow/credentials.json` | Auth token, app, API key, config - global (use `login --global`) |
417
+ | `.securenow/credentials.json` | Auth token, app, API key, config, explanations - project-local default |
428
418
 
429
- **Resolution order:** `SECURENOW_TOKEN` env var → project `.securenow/credentials.json` → global `~/.securenow/credentials.json`.
419
+ **Resolution order:** project `.securenow/credentials.json` → global `~/.securenow/credentials.json`. Legacy CLI token overrides still work for existing automation.
430
420
 
431
421
  ### Global Flags
432
422
 
@@ -449,31 +439,31 @@ Every command supports these flags:
449
439
 
450
440
  ### Multi-Project Sessions
451
441
 
452
- Use `--local` to maintain separate logins per project on the same machine:
442
+ Project-local credentials are the default, so separate projects can use separate SecureNow apps on the same machine:
453
443
 
454
444
  ```bash
455
445
  # In project A — log in as user-a@company.com
456
446
  cd ~/projects/project-a
457
- npx securenow login --local
447
+ npx securenow login
458
448
 
459
449
  # In project B — log in as user-b@company.com
460
450
  cd ~/projects/project-b
461
- npx securenow login --local
451
+ npx securenow login
462
452
 
463
453
  # Each project uses its own credentials independently
464
454
  npx securenow whoami # Shows auth source: project (.securenow/)
465
455
  ```
466
456
 
467
- You can also use the `SECURENOW_TOKEN` env var for per-terminal sessions without touching any files.
457
+ For new automation, prefer project-local or runtime credentials files. `SECURENOW_TOKEN` remains a legacy fallback for per-terminal sessions.
468
458
 
469
459
  ### CI/CD Integration
470
460
 
471
461
  ```bash
472
- # Authenticate with a token in CI (env var no file needed)
473
- SECURENOW_TOKEN=$MY_SECRET npx securenow logs --json
462
+ # Generate a tokenless runtime file from a logged-in project
463
+ npx securenow credentials runtime --env production
474
464
 
475
- # Or use login with explicit token
476
- npx securenow login --token $SECURENOW_TOKEN
465
+ # Store .securenow/credentials.production.json as a deployment secret file,
466
+ # then materialize it as .securenow/credentials.json in the running app.
477
467
 
478
468
  # Use --json for machine-readable output
479
469
  npx securenow logs --json --level error | jq '.logs'
@@ -545,7 +535,7 @@ npx securenow logs --json --level error | jq '.logs'
545
535
  | **Utilities** | `redact '<json>' [--fields f1,f2]` | Redact sensitive fields (accepts `@file.json`) |
546
536
  | | `cidr match <ip> <cidrs>` | IP vs. CIDR list (exit 0 hit / 2 miss) |
547
537
  | | `cidr parse <cidr>` | Parse CIDR (network, broadcast, mask, size) |
548
- | | `env [--json]` | Show resolved config (service name, endpoints, env vars) |
538
+ | | `env [--json]` | Show resolved config (service name, endpoints, credentials) |
549
539
  | | `doctor [--json]` | Probe OTLP + API endpoints, check config |
550
540
  | **Settings** | `instances` | List instances |
551
541
  | | `instances test <id>` | Test connection |
@@ -598,19 +588,11 @@ module.exports = {
598
588
  name: 'my-app',
599
589
  script: './app.js',
600
590
  node_args: '-r securenow/register',
601
- env: {
602
- SECURENOW_APPID: 'your-app-key',
603
- SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
604
- SECURENOW_API_KEY: 'snk_live_abc123...',
605
- SECURENOW_LOGGING_ENABLED: '1',
606
- SECURENOW_NO_UUID: '1',
607
- SECURENOW_CAPTURE_BODY: '1',
608
- }
609
591
  }]
610
592
  };
611
593
  ```
612
594
 
613
- > **Important:** Always use `node_args: '-r securenow/register'` in PM2 configs. Without it, PM2 restarts won't load the SDK, and the firewall won't activate.
595
+ > **Important:** Put `.securenow/credentials.json` in the PM2 app root and keep `node_args: '-r securenow/register'`. PM2 restarts will then load the SDK, traces/logs, body capture, and firewall without any SecureNow env vars.
614
596
 
615
597
  ---
616
598
 
@@ -955,70 +937,50 @@ app.listen(3000, () => console.log('Feathers running on port 3000'));
955
937
 
956
938
  See [Next.js Complete Guide](./docs/NEXTJS-SETUP-COMPLETE.md) for the full reference.
957
939
 
958
- #### Option A: `withSecureNow()` wrapper (v5.13.0+ -- Recommended)
959
-
960
- One wrapper handles everything: `serverExternalPackages` (Next 15) or `experimental.serverComponentsExternalPackages` (Next 14), `instrumentationHook`, and webpack warning suppression.
940
+ #### Option A: `securenow init` (Recommended)
961
941
 
962
- **1. Update `next.config.js`:**
963
-
964
- ```javascript
965
- const { withSecureNow } = require('securenow/nextjs-webpack-config');
942
+ The init command handles the boring parts: credentials defaults, `instrumentation.ts`, body auto-capture, and `serverExternalPackages` for Next 15+. If existing files are custom, it prints a Codex/Claude-ready prompt instead of guessing.
966
943
 
967
- module.exports = withSecureNow({
968
- // your existing config -- reactStrictMode, images, rewrites, etc.
969
- });
944
+ ```bash
945
+ npx securenow login
946
+ npx securenow init
970
947
  ```
971
948
 
972
- **2. Create `instrumentation.ts` (or `.js`):**
949
+ **Generated `instrumentation.ts` (or `.js`):**
973
950
 
974
951
  ```typescript
952
+ import { createRequire } from 'node:module';
953
+
954
+ const require = createRequire(import.meta.url);
955
+
975
956
  export async function register() {
976
- if (process.env.NEXT_RUNTIME === 'nodejs') {
977
- const { registerSecureNow } = require('securenow/nextjs');
978
- registerSecureNow();
979
- }
957
+ if (process.env.NEXT_RUNTIME !== 'nodejs') return;
958
+ const { registerSecureNow } = require('securenow/nextjs');
959
+ registerSecureNow({ captureBody: true });
960
+ require('securenow/nextjs-auto-capture');
980
961
  }
981
962
  ```
982
963
 
983
- Or run `npx securenow init` to auto-generate this file.
964
+ **Next.js 15+ `next.config.*`:**
984
965
 
985
- **3. Set environment variables in `.env.local`:**
966
+ ```javascript
967
+ const nextConfig = {
968
+ serverExternalPackages: ['securenow'],
969
+ };
986
970
 
987
- ```env
988
- SECURENOW_APPID=my-nextjs-app
989
- SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
990
- SECURENOW_API_KEY=snk_live_abc123...
991
- SECURENOW_LOGGING_ENABLED=1
992
- SECURENOW_NO_UUID=1
971
+ export default nextConfig;
993
972
  ```
994
973
 
995
- That's it. `withSecureNow()` auto-detects your Next.js version and configures:
996
- - **Next.js 15+**: Sets `serverExternalPackages` with all 13 required OTel packages
997
- - **Next.js 14**: Sets `experimental.serverComponentsExternalPackages` and `experimental.instrumentationHook: true`
998
- - **Both**: Suppresses webpack warnings from OpenTelemetry instrumentation packages
974
+ No `.env.local` is needed locally or in production. Use `npx securenow credentials runtime --env production` and mount/copy the resulting JSON as `.securenow/credentials.json`.
999
975
 
1000
976
  #### Option B: Manual configuration
1001
977
 
1002
- If you prefer not to use the wrapper, manually add the packages:
978
+ If you prefer not to run `init`, manually externalize SecureNow:
1003
979
 
1004
980
  ```javascript
1005
981
  // next.config.js (Next.js 15+)
1006
982
  module.exports = {
1007
- serverExternalPackages: [
1008
- 'securenow',
1009
- '@opentelemetry/sdk-node',
1010
- '@opentelemetry/auto-instrumentations-node',
1011
- '@opentelemetry/instrumentation-http',
1012
- '@opentelemetry/exporter-trace-otlp-http',
1013
- '@opentelemetry/exporter-logs-otlp-http',
1014
- '@opentelemetry/sdk-logs',
1015
- '@opentelemetry/instrumentation',
1016
- '@opentelemetry/resources',
1017
- '@opentelemetry/semantic-conventions',
1018
- '@opentelemetry/api',
1019
- '@opentelemetry/api-logs',
1020
- '@vercel/otel',
1021
- ],
983
+ serverExternalPackages: ['securenow'],
1022
984
  };
1023
985
  ```
1024
986
 
@@ -1027,26 +989,12 @@ module.exports = {
1027
989
  module.exports = {
1028
990
  experimental: {
1029
991
  instrumentationHook: true,
1030
- serverComponentsExternalPackages: [
1031
- 'securenow',
1032
- '@opentelemetry/sdk-node',
1033
- '@opentelemetry/auto-instrumentations-node',
1034
- '@opentelemetry/instrumentation-http',
1035
- '@opentelemetry/exporter-trace-otlp-http',
1036
- '@opentelemetry/exporter-logs-otlp-http',
1037
- '@opentelemetry/sdk-logs',
1038
- '@opentelemetry/instrumentation',
1039
- '@opentelemetry/resources',
1040
- '@opentelemetry/semantic-conventions',
1041
- '@opentelemetry/api',
1042
- '@opentelemetry/api-logs',
1043
- '@vercel/otel',
1044
- ],
992
+ serverComponentsExternalPackages: ['securenow'],
1045
993
  },
1046
994
  };
1047
995
  ```
1048
996
 
1049
- **Why is this needed?** Next.js bundles server code with webpack, which breaks OpenTelemetry's dynamic `require()` calls and monkey-patching. Externalizing these packages keeps them as normal Node.js `require()` calls at runtime. The `withSecureNow()` wrapper handles this automatically.
997
+ **Why is this needed?** Next.js bundles server code with webpack, which can break OpenTelemetry's dynamic `require()` calls and monkey-patching. Externalizing `securenow` keeps the SDK as normal Node.js runtime code.
1050
998
 
1051
999
  ---
1052
1000
 
@@ -1064,13 +1012,7 @@ export default defineNuxtConfig({
1064
1012
  });
1065
1013
  ```
1066
1014
 
1067
- `.env`:
1068
-
1069
- ```env
1070
- SECURENOW_APPID=my-nuxt-app
1071
- SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
1072
- SECURENOW_API_KEY=snk_live_abc123...
1073
- ```
1015
+ Local and production app identity and secure defaults come from `.securenow/credentials.json`.
1074
1016
 
1075
1017
  That's it -- the Nuxt module handles OTel SDK initialization, Nitro externalization, firewall activation, and request tracing automatically. Optional config:
1076
1018
 
@@ -1103,14 +1045,14 @@ The Nuxt server plugin (v5.13.0+) initializes the firewall independently from Op
1103
1045
  | Micro/HTTP | Yes | Yes | Yes | Yes | Full control |
1104
1046
  | Hono | Yes | Yes | Yes | Yes | Use ESM `-r` preload |
1105
1047
  | Feathers | Yes | Yes | Yes | Yes | Uses Express transport |
1106
- | Next.js | Yes | Yes | Yes | Yes | Use `instrumentation.ts` + `withSecureNow()` |
1048
+ | Next.js | Yes | Yes | Yes | Yes | Use `instrumentation.ts` + `serverExternalPackages: ['securenow']` |
1107
1049
  | Nuxt 3 | Yes | Yes | Yes | Yes | Use `securenow/nuxt` module |
1108
1050
 
1109
1051
  ---
1110
1052
 
1111
1053
  ## Firewall -- Automatic IP Blocking
1112
1054
 
1113
- SecureNow can automatically block IPs from your blocklist at the application layer. No code changes -- just provide an API key (via `securenow login`, the `api-key` CLI, or env var) and the firewall activates.
1055
+ SecureNow can automatically block IPs from your blocklist at the application layer. No code changes -- provide an API key via `securenow login`, the `api-key` CLI, or a runtime credentials file and the firewall activates.
1114
1056
 
1115
1057
  ### Firewall Is Enabled by Default
1116
1058
 
@@ -1124,12 +1066,11 @@ npx securenow login
1124
1066
  # (b) Already have a key? Write it to the creds file directly:
1125
1067
  npx securenow api-key set snk_live_abc123...
1126
1068
 
1127
- # (c) Old-school env var (still works; preferred for CI/Docker/prod):
1128
- # .env
1129
- SECURENOW_API_KEY=snk_live_abc123...
1069
+ # (c) Production? Generate a tokenless runtime credentials file:
1070
+ npx securenow credentials runtime --env production
1130
1071
  ```
1131
1072
 
1132
- The SDK resolves the firewall key in this order: `SECURENOW_API_KEY` env var (only if it starts with `snk_live_`) → project `./.securenow/credentials.json` global `~/.securenow/credentials.json`.
1073
+ The SDK resolves the firewall key from project `./.securenow/credentials.json`, then global `~/.securenow/credentials.json`. Legacy `SECURENOW_API_KEY` overrides still work for existing deployments.
1133
1074
 
1134
1075
  On startup, you'll see:
1135
1076
 
@@ -1178,15 +1119,11 @@ This is useful when:
1178
1119
  - You're adding the firewall to a project that uses a different tracing solution
1179
1120
  - For Next.js, this avoids the need for `serverExternalPackages` entirely
1180
1121
 
1181
- Environment variables for firewall-only mode:
1122
+ Firewall-only mode uses the same `.securenow/credentials.json` key written by `login`, `api-key set`, or mounted from a runtime credentials file:
1182
1123
 
1183
1124
  ```bash
1184
- SECURENOW_API_KEY=snk_live_abc123... # Required
1185
- SECURENOW_API_URL=https://api.securenow.ai # Optional (auto-detected)
1186
- SECURENOW_FIREWALL_ENABLED=1 # Default: 1
1187
- SECURENOW_FIREWALL_TCP=1 # Optional: Layer 2
1188
- SECURENOW_FIREWALL_IPTABLES=1 # Optional: Layer 3
1189
- SECURENOW_FIREWALL_CLOUD=cloudflare # Optional: Layer 4
1125
+ npx securenow credentials runtime --env production
1126
+ node -r securenow/firewall-only app.js
1190
1127
  ```
1191
1128
 
1192
1129
  ### Blocking Layers
@@ -1220,14 +1157,34 @@ See the [Firewall Guide](./docs/FIREWALL-GUIDE.md) for the full reference.
1220
1157
 
1221
1158
  ---
1222
1159
 
1223
- ## Environment Variables Reference
1160
+ ## Credentials Configuration
1161
+
1162
+ Local development and production use `.securenow/credentials.json`. Run `npx securenow login` and `npx securenow init`; for production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json`.
1163
+
1164
+ See [docs/ENVIRONMENT-VARIABLES.md](./docs/ENVIRONMENT-VARIABLES.md) and [docs/ENVIRONMENTS.md](./docs/ENVIRONMENTS.md) for the full credentials and environment reference.
1165
+
1166
+ ### Credentials Fields
1224
1167
 
1225
- ### Required Variables
1168
+ | Field | Description | Default |
1169
+ |----------|-------------|---------|
1170
+ | `app.key` | SecureNow app routing UUID / OTel service name. | chosen during login |
1171
+ | `app.instance` | OTLP collector base URL. | `https://freetrial.securenow.ai:4318` |
1172
+ | `apiKey` | Scoped firewall key (`snk_live_...`). | minted during login |
1173
+ | `config.runtime.deploymentEnvironment` | `deployment.environment` trace/log scope. | `local` from init, `production` from runtime credentials |
1174
+ | `config.logging.enabled` | Automatic console log export. | `true` |
1175
+ | `config.capture.body` | Request body capture with redaction. | `true` |
1176
+ | `config.capture.multipart` | Multipart metadata capture, never file content. | `true` |
1177
+ | `config.firewall.enabled` | Local SDK firewall switch; dashboard toggle is per environment. | `true` |
1178
+ | `config.otel.*` | Optional custom endpoints, headers, and log level. | empty |
1179
+
1180
+ Legacy env fallback aliases are listed below for existing installs only.
1181
+
1182
+ ### Legacy App Identity Fallbacks
1226
1183
 
1227
1184
  | Variable | Description | Example |
1228
1185
  |----------|-------------|---------|
1229
- | `SECURENOW_APPID` | Your application identifier. Used as the service name in traces. | `my-app` |
1230
- | `SECURENOW_INSTANCE` | Base URL of your OTLP collector endpoint. | `http://localhost:4318` |
1186
+ | `SECURENOW_APPID` | Fallback for missing credentials `app.key`. Used as the app routing key/service name. | `<uuid>` |
1187
+ | `SECURENOW_INSTANCE` | Fallback for missing credentials `app.instance`. Base URL of your OTLP collector endpoint. | `https://freetrial.securenow.ai:4318` |
1231
1188
 
1232
1189
  ### Optional Configuration
1233
1190
 
@@ -1235,18 +1192,18 @@ See the [Firewall Guide](./docs/FIREWALL-GUIDE.md) for the full reference.
1235
1192
 
1236
1193
  | Variable | Description | Default |
1237
1194
  |----------|-------------|---------|
1238
- | `OTEL_SERVICE_NAME` | Alternative to SECURENOW_APPID. Standard OpenTelemetry variable. | - |
1239
- | `SECURENOW_NO_UUID` | Set to `1` to disable UUID suffix on service name. Useful for clustered apps. | `0` |
1240
- | `SECURENOW_STRICT` | Set to `1` to exit process if SECURENOW_APPID is not set in cluster mode. | `0` |
1195
+ | `OTEL_SERVICE_NAME` | Fallback for missing `app.name`. Standard OpenTelemetry variable. | - |
1196
+ | `SECURENOW_NO_UUID` | Legacy fallback for `config.runtime.noUuid`. | `0` |
1197
+ | `SECURENOW_STRICT` | Legacy fallback for `config.runtime.strict`. | `0` |
1241
1198
 
1242
1199
  #### Connection Settings
1243
1200
 
1244
1201
  | Variable | Description | Default |
1245
1202
  |----------|-------------|---------|
1246
- | `OTEL_EXPORTER_OTLP_ENDPOINT` | Alternative to SECURENOW_INSTANCE. Standard OpenTelemetry variable. | - |
1247
- | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Override traces endpoint specifically. | `{SECURENOW_INSTANCE}/v1/traces` |
1248
- | `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Override logs endpoint specifically. | `{SECURENOW_INSTANCE}/v1/logs` |
1249
- | `OTEL_EXPORTER_OTLP_HEADERS` | Headers to send with OTLP exports. Format: `key1=value1,key2=value2` | - |
1203
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | Fallback for `config.otel.endpoint`. | - |
1204
+ | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Fallback for `config.otel.tracesEndpoint`. | `{instance}/v1/traces` |
1205
+ | `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Fallback for `config.otel.logsEndpoint`. | `{instance}/v1/logs` |
1206
+ | `OTEL_EXPORTER_OTLP_HEADERS` | Fallback for `config.otel.headers`. Format: `key1=value1,key2=value2` | - |
1250
1207
 
1251
1208
  #### Logging
1252
1209
 
@@ -1277,7 +1234,7 @@ See the [Firewall Guide](./docs/FIREWALL-GUIDE.md) for the full reference.
1277
1234
 
1278
1235
  | Variable | Description | Default |
1279
1236
  |----------|-------------|---------|
1280
- | `SECURENOW_API_KEY` | API key with `firewall:read` scope. Enables the firewall when set. Since v7.1.0 the firewall also reads this from `.securenow/credentials.json` (written by `securenow login` or `securenow api-key set`); env var only wins if it starts with `snk_live_`. | from creds file |
1237
+ | `SECURENOW_API_KEY` | Legacy firewall key override. Prefer `apiKey` in `.securenow/credentials.json`. | from creds file |
1281
1238
  | `SECURENOW_API_URL` | SecureNow API base URL. Auto-detected for co-located deployments (falls back to `http://localhost:4000` on ECONNREFUSED). | `https://api.securenow.ai` |
1282
1239
  | `SECURENOW_FIREWALL_ENABLED` | Master kill-switch. Set to `0` to disable. | `1` |
1283
1240
  | `SECURENOW_FIREWALL_VERSION_INTERVAL` | Seconds between version checks (lightweight ETag-based). | `10` |
@@ -1304,7 +1261,7 @@ See [Firewall Guide](./docs/FIREWALL-GUIDE.md) for complete details on all layer
1304
1261
 
1305
1262
  | Variable | Description | Default |
1306
1263
  |----------|-------------|---------|
1307
- | `NODE_ENV` | Deployment environment name. Sent as `deployment.environment` attribute. | `production` |
1264
+ | `SECURENOW_ENVIRONMENT` / `SECURENOW_DEPLOYMENT_ENVIRONMENT` / `NODE_ENV` | Fallback for `config.runtime.deploymentEnvironment`. | `production` |
1308
1265
 
1309
1266
  ---
1310
1267
 
@@ -1388,11 +1345,7 @@ logger.emit({
1388
1345
 
1389
1346
  ```bash
1390
1347
  # Enable tracing + logging (console auto-forwarding is built-in since v5.6.0)
1391
- NODE_OPTIONS="-r securenow/register" \
1392
- SECURENOW_APPID=my-app \
1393
- SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318 \
1394
- SECURENOW_LOGGING_ENABLED=1 \
1395
- node app.js
1348
+ node -r securenow/register app.js
1396
1349
  ```
1397
1350
 
1398
1351
  ---
@@ -1472,41 +1425,34 @@ export SECURENOW_SENSITIVE_FIELDS="custom_secret,internal_token"
1472
1425
 
1473
1426
  ### Complete Example with All Options
1474
1427
 
1475
- ```bash
1476
- # Service identification
1477
- export SECURENOW_APPID=my-production-app
1478
- export SECURENOW_NO_UUID=1
1479
- export SECURENOW_STRICT=1
1480
-
1481
- # OTLP backend
1482
- export SECURENOW_INSTANCE=http://collector.example.com:4318
1483
- export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key"
1484
-
1485
- # Logging
1486
- export SECURENOW_LOGGING_ENABLED=1
1487
-
1488
- # Request body capture
1489
- export SECURENOW_CAPTURE_BODY=1
1490
- export SECURENOW_MAX_BODY_SIZE=20480
1491
- export SECURENOW_SENSITIVE_FIELDS="internal_id,session_key"
1492
-
1493
- # Firewall
1494
- export SECURENOW_API_KEY=snk_live_abc123...
1495
- export SECURENOW_FIREWALL_TCP=1
1496
- export SECURENOW_FIREWALL_VERSION_INTERVAL=10
1497
- export SECURENOW_FIREWALL_SYNC_INTERVAL=300
1498
-
1499
- # Environment
1500
- export NODE_ENV=production
1501
-
1502
- # Debugging
1503
- export OTEL_LOG_LEVEL=info
1504
-
1505
- # Disable specific instrumentations
1506
- export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns
1507
-
1508
- # Run application
1509
- NODE_OPTIONS="-r securenow/register" node app.js
1428
+ ```json
1429
+ {
1430
+ "apiKey": "snk_live_...",
1431
+ "app": {
1432
+ "key": "my-production-app",
1433
+ "name": "my-production-app",
1434
+ "instance": "http://collector.example.com:4318"
1435
+ },
1436
+ "config": {
1437
+ "runtime": { "noUuid": true, "strict": true, "deploymentEnvironment": "production" },
1438
+ "otel": {
1439
+ "headers": { "x-api-key": "your-api-key" },
1440
+ "logLevel": "info",
1441
+ "disableInstrumentations": ["fs", "dns"]
1442
+ },
1443
+ "logging": { "enabled": true },
1444
+ "capture": {
1445
+ "body": true,
1446
+ "maxBodySize": 20480,
1447
+ "sensitiveFields": ["internal_id", "session_key"]
1448
+ },
1449
+ "firewall": {
1450
+ "tcp": true,
1451
+ "versionCheckInterval": 10,
1452
+ "syncInterval": 300
1453
+ }
1454
+ }
1455
+ }
1510
1456
  ```
1511
1457
 
1512
1458
  ### Using Multiple Logger Instances
@@ -1547,15 +1493,10 @@ if (isLoggingEnabled()) {
1547
1493
 
1548
1494
  ### Programmatic Configuration
1549
1495
 
1550
- While environment variables are recommended, you can also configure programmatically:
1496
+ Use `.securenow/credentials.json` for local development, tests, CI, and production:
1551
1497
 
1552
1498
  ```javascript
1553
- // Set environment variables before requiring securenow
1554
- process.env.SECURENOW_APPID = 'my-app';
1555
- process.env.SECURENOW_INSTANCE = 'http://localhost:4318';
1556
- process.env.SECURENOW_LOGGING_ENABLED = '1';
1557
-
1558
- // Then initialize (console log forwarding is automatic since v5.6.0)
1499
+ // Reads .securenow/credentials.json from the project root.
1559
1500
  require('securenow/register');
1560
1501
  ```
1561
1502
 
@@ -1636,14 +1577,14 @@ bootstrap();
1636
1577
 
1637
1578
  ### Traces Not Appearing
1638
1579
 
1639
- **Check 1: Verify environment variables**
1580
+ **Check 1: Verify credentials resolution**
1640
1581
 
1641
1582
  ```bash
1642
- echo $SECURENOW_APPID
1643
- echo $SECURENOW_INSTANCE
1583
+ npx securenow env
1584
+ npx securenow status --env local
1644
1585
  ```
1645
1586
 
1646
- Both should output values.
1587
+ The output should show an app key, collector endpoint, and deployment environment from `.securenow/credentials.json`.
1647
1588
 
1648
1589
  **Check 2: Verify OTLP collector is running**
1649
1590
 
@@ -1652,11 +1593,14 @@ curl http://localhost:4318/v1/traces
1652
1593
  # Should return 200 or 405 (method not allowed)
1653
1594
  ```
1654
1595
 
1655
- **Check 3: Enable debug logging**
1596
+ **Check 3: Enable debug logging in credentials**
1656
1597
 
1657
- ```bash
1658
- export OTEL_LOG_LEVEL=debug
1659
- node app.js
1598
+ ```json
1599
+ {
1600
+ "config": {
1601
+ "otel": { "logLevel": "debug" }
1602
+ }
1603
+ }
1660
1604
  ```
1661
1605
 
1662
1606
  Look for lines like:
@@ -1680,10 +1624,10 @@ require('securenow/register');
1680
1624
 
1681
1625
  ### Firewall Not Blocking IPs
1682
1626
 
1683
- **Check 1: Is `SECURENOW_API_KEY` set?**
1627
+ **Check 1: Is an API key in `.securenow/credentials.json`?**
1684
1628
 
1685
1629
  ```bash
1686
- echo $SECURENOW_API_KEY
1630
+ npx securenow api-key show
1687
1631
  ```
1688
1632
 
1689
1633
  **Check 2: Is the IP in the blocklist?**
@@ -1709,7 +1653,7 @@ After blocking an IP, it takes 10-15 seconds to propagate (one version-check int
1709
1653
 
1710
1654
  **Check 5: Are you behind a proxy?**
1711
1655
 
1712
- Set `SECURENOW_TRUSTED_PROXIES` to your proxy's IP so the firewall sees the real client IP.
1656
+ Add your proxy IPs to `config.networking.trustedProxies` in `.securenow/credentials.json` so the firewall sees the real client IP.
1713
1657
 
1714
1658
  **Check 6: Using PM2?**
1715
1659
 
@@ -1719,9 +1663,12 @@ Make sure `node_args: '-r securenow/register'` is in your `ecosystem.config.cjs`
1719
1663
 
1720
1664
  **Check 1: Is logging enabled?**
1721
1665
 
1722
- ```bash
1723
- echo $SECURENOW_LOGGING_ENABLED
1724
- # Should output: 1
1666
+ ```json
1667
+ {
1668
+ "config": {
1669
+ "logging": { "enabled": true }
1670
+ }
1671
+ }
1725
1672
  ```
1726
1673
 
1727
1674
  **Check 2: Verify console instrumentation is loaded**
@@ -1748,9 +1695,12 @@ curl http://localhost:4318/v1/logs
1748
1695
 
1749
1696
  **Check 1: Make sure body capture was not explicitly disabled**
1750
1697
 
1751
- ```bash
1752
- echo $SECURENOW_CAPTURE_BODY
1753
- # Should be empty, 1, or true. Remove SECURENOW_CAPTURE_BODY=0 to re-enable defaults.
1698
+ ```json
1699
+ {
1700
+ "config": {
1701
+ "capture": { "body": true }
1702
+ }
1703
+ }
1754
1704
  ```
1755
1705
 
1756
1706
  **Check 2: Verify content type**
@@ -1762,42 +1712,59 @@ Body capture only works for:
1762
1712
 
1763
1713
  **Check 3: Check body size**
1764
1714
 
1765
- Bodies larger than `SECURENOW_MAX_BODY_SIZE` are truncated:
1715
+ Bodies larger than `config.capture.maxBodySize` are truncated:
1766
1716
 
1767
- ```bash
1768
- export SECURENOW_MAX_BODY_SIZE=20480 # Increase to 20KB
1717
+ ```json
1718
+ {
1719
+ "config": {
1720
+ "capture": { "maxBodySize": 20480 }
1721
+ }
1722
+ }
1769
1723
  ```
1770
1724
 
1771
1725
  ### High Memory Usage
1772
1726
 
1773
1727
  **Option 1: Disable body capture**
1774
1728
 
1775
- ```bash
1776
- export SECURENOW_CAPTURE_BODY=0
1729
+ ```json
1730
+ {
1731
+ "config": {
1732
+ "capture": { "body": false }
1733
+ }
1734
+ }
1777
1735
  ```
1778
1736
 
1779
1737
  **Option 2: Reduce body size limit**
1780
1738
 
1781
- ```bash
1782
- export SECURENOW_MAX_BODY_SIZE=5120 # 5KB
1739
+ ```json
1740
+ {
1741
+ "config": {
1742
+ "capture": { "maxBodySize": 5120 }
1743
+ }
1744
+ }
1783
1745
  ```
1784
1746
 
1785
1747
  **Option 3: Disable specific instrumentations**
1786
1748
 
1787
- ```bash
1788
- export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns,net
1749
+ ```json
1750
+ {
1751
+ "config": {
1752
+ "otel": { "disableInstrumentations": ["fs", "dns", "net"] }
1753
+ }
1754
+ }
1789
1755
  ```
1790
1756
 
1791
1757
  ### Next.js Instrumentation Not Working
1792
1758
 
1793
- **Check 1: Using `withSecureNow()`?**
1759
+ **Check 1: Is `securenow` externalized?**
1794
1760
 
1795
1761
  ```javascript
1796
- const { withSecureNow } = require('securenow/nextjs-webpack-config');
1797
- module.exports = withSecureNow({ /* your config */ });
1762
+ module.exports = {
1763
+ serverExternalPackages: ['securenow'],
1764
+ };
1798
1765
  ```
1799
1766
 
1800
- This auto-handles `serverExternalPackages` / `experimental.serverComponentsExternalPackages` and `instrumentationHook` based on your Next.js version.
1767
+ For Next.js < 15, add `securenow` to `experimental.serverComponentsExternalPackages` and enable `experimental.instrumentationHook`.
1801
1768
 
1802
1769
  **Check 2: Verify instrumentation file location**
1803
1770
 
@@ -1805,7 +1772,7 @@ This auto-handles `serverExternalPackages` / `experimental.serverComponentsExter
1805
1772
 
1806
1773
  **Check 3: Check for OTel MODULE_NOT_FOUND errors**
1807
1774
 
1808
- If you see `MODULE_NOT_FOUND` for `@opentelemetry/*` packages, your `next.config.js` is missing the externalization. Use `withSecureNow()` to fix this automatically.
1775
+ If you see `MODULE_NOT_FOUND` for `@opentelemetry/*` packages, your `next.config.js` is missing the externalization. Run `npx securenow init`; if your config is custom, use the prompt it prints to merge the edit safely.
1809
1776
 
1810
1777
  **Check 4: Restart dev server**
1811
1778
 
@@ -1818,10 +1785,14 @@ npm run dev
1818
1785
 
1819
1786
  **Problem: Different service names for each worker**
1820
1787
 
1821
- **Solution: Use SECURENOW_NO_UUID**
1788
+ **Solution: Set `config.runtime.noUuid`**
1822
1789
 
1823
- ```bash
1824
- export SECURENOW_NO_UUID=1
1790
+ ```json
1791
+ {
1792
+ "config": {
1793
+ "runtime": { "noUuid": true }
1794
+ }
1795
+ }
1825
1796
  ```
1826
1797
 
1827
1798
  This uses the same service name for all workers.
@@ -1838,11 +1809,6 @@ module.exports = {
1838
1809
  script: './app.js',
1839
1810
  instances: 4,
1840
1811
  node_args: '-r securenow/register',
1841
- env: {
1842
- SECURENOW_APPID: 'my-app',
1843
- SECURENOW_INSTANCE: 'http://localhost:4318',
1844
- SECURENOW_API_KEY: 'snk_live_abc123...',
1845
- }
1846
1812
  }]
1847
1813
  };
1848
1814
  ```
@@ -1853,18 +1819,16 @@ Without `node_args`, PM2 starts your script directly without the securenow prelo
1853
1819
 
1854
1820
  ## Best Practices
1855
1821
 
1856
- ### 1. Use Environment Variables
1822
+ ### 1. Use the Credentials File
1857
1823
 
1858
- Don't hardcode configuration. Use environment variables:
1824
+ Do not hardcode configuration in code or deployment dashboards. Use `.securenow/credentials.json` locally and mount the tokenless runtime file in production:
1859
1825
 
1860
1826
  ```javascript
1861
1827
  // Bad
1862
1828
  process.env.SECURENOW_APPID = 'hardcoded-value';
1863
1829
 
1864
- // Good -- use .env file or export
1865
- // .env
1866
- SECURENOW_APPID=my-app
1867
- SECURENOW_INSTANCE=http://localhost:4318
1830
+ // Good: use .securenow/credentials.json
1831
+ // { "app": { "key": "my-app", "instance": "https://freetrial.securenow.ai:4318" } }
1868
1832
  ```
1869
1833
 
1870
1834
  ### 2. Use Structured Logging
@@ -1933,12 +1897,12 @@ const apiLogger = getLogger('api', '1.0.0');
1933
1897
 
1934
1898
  ### 6. Disable Body Capture Outside Development
1935
1899
 
1936
- ```bash
1937
- # .env.development
1938
- SECURENOW_CAPTURE_BODY=1
1939
-
1940
- # .env.production
1941
- SECURENOW_CAPTURE_BODY=0
1900
+ ```json
1901
+ {
1902
+ "config": {
1903
+ "capture": { "body": false }
1904
+ }
1905
+ }
1942
1906
  ```
1943
1907
 
1944
1908
  ---