securenow 7.5.1 → 7.6.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.
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 +209 -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 +208 -206
  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 +71 -39
  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 +24 -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 +47 -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
@@ -1,892 +1,166 @@
1
- # SecureNow Environment Variables Reference
1
+ # SecureNow Credentials Reference
2
2
 
3
- Complete reference for all environment variables supported by SecureNow.
3
+ SecureNow uses `.securenow/credentials.json` in local development and production. No `.env` file is required.
4
4
 
5
- > **v7+: env vars are all optional.** For local dev, `npx securenow login` writes `.securenow/credentials.json` and the SDK reads it at boot — no env vars needed. Env vars are still supported (and always take precedence) for CI / Docker / production.
6
-
7
- > **Resolution order** (first non-empty wins): env var → `./.securenow/credentials.json` → `~/.securenow/credentials.json` → `package.json#name` (label only) → default.
8
-
9
- ---
10
-
11
- ## Quick Reference Table
12
-
13
- | Variable | Type | Default | Description |
14
- |----------|------|---------|-------------|
15
- | **SECURENOW_APPID** | Optional | from credentials file | App routing key (UUID). Sent as OTel `service.name`. |
16
- | **SECURENOW_INSTANCE** | Optional | `https://freetrial.securenow.ai:4318` | OTLP collector base URL |
17
- | **SECURENOW_API_KEY** | Optional | from credentials file | API key (same UUID as APPID). Enables firewall. |
18
- | **SECURENOW_LOGGING_ENABLED** | Optional | `1` (on) | Forward `console.*` as OTLP logs. Set to `0` to disable. |
19
- | **SECURENOW_CAPTURE_BODY** | Optional | `1` (on) | Capture request body. Set to `0` only for a local stream conflict. |
20
- | **SECURENOW_CAPTURE_MULTIPART** | Optional | `1` (on) | Capture multipart field/file metadata. |
21
- | **SECURENOW_MAX_BODY_SIZE** | Optional | `10240` | Max body size in bytes |
22
- | **SECURENOW_SENSITIVE_FIELDS** | Optional | - | Comma-separated extra fields to redact |
23
- | **SECURENOW_NO_UUID** | Optional | `0` | Disable UUID suffix on `service.instance.id` |
24
- | **SECURENOW_STRICT** | Optional | `0` | Exit if APPID missing in PM2 cluster mode |
25
- | **SECURENOW_DISABLE_INSTRUMENTATIONS** | Optional | - | Comma-separated list of OTel instrumentations to disable |
26
- | **SECURENOW_TEST_SPAN** | Optional | `0` | Emit a single test span on startup (prefer `npx securenow test-span`) |
27
- | **SECURENOW_HIDE_BANNER** | Optional | `0` | Hide the free-trial banner |
28
- | **SECURENOW_FIREWALL_ENABLED** | Optional | (dashboard toggle) | Local override only — set to `0` to force-off regardless of dashboard. Primary control is the per-app toggle at `/dashboard/firewall` (≥ 7.3.0). |
29
- | **SECURENOW_ENABLE_MONGODB_INSTRUMENTATION** | Optional | `0` | Opt in to MongoDB instrumentation (off by default since a cursor bug on mongodb@6.6+; safe since SDK v6.0.2) |
30
- | **OTEL_SERVICE_NAME** | Optional | - | Alternative to SECURENOW_APPID (label only, no routing) |
31
- | **OTEL_EXPORTER_OTLP_ENDPOINT** | Optional | - | Alternative to SECURENOW_INSTANCE |
32
- | **OTEL_EXPORTER_OTLP_HEADERS** | Optional | auto (`x-api-key` injected) | Additional OTLP headers |
33
- | **OTEL_EXPORTER_OTLP_TRACES_ENDPOINT** | Optional | - | Override traces endpoint |
34
- | **OTEL_EXPORTER_OTLP_LOGS_ENDPOINT** | Optional | - | Override logs endpoint |
35
- | **OTEL_LOG_LEVEL** | Optional | `none` | SDK log verbosity (`debug`/`info`/`warn`/`error`) |
36
- | **NODE_ENV** | Optional | `production` | Environment name |
37
- | **SECURENOW_API_URL** | Optional | `https://api.securenow.ai` | Dashboard API base URL |
38
- | **SECURENOW_APP_URL** | Optional | `https://app.securenow.ai` | Dashboard web base URL |
39
- | **SECURENOW_TOKEN** | Optional | from credentials file | Auth token (overrides credentials file for CI) |
40
- | **SECURENOW_FIREWALL_ENABLED** | Optional | `1` | Firewall master kill-switch |
41
- | **SECURENOW_FIREWALL_SYNC_INTERVAL** | Optional | `60` | Blocklist refresh interval (seconds) |
42
- | **SECURENOW_FIREWALL_FAIL_MODE** | Optional | `open` | Behavior when API unreachable: open/closed |
43
- | **SECURENOW_FIREWALL_STATUS_CODE** | Optional | `403` | HTTP status for blocked requests |
44
- | **SECURENOW_FIREWALL_LOG** | Optional | `1` | Log blocked requests |
45
- | **SECURENOW_FIREWALL_TCP** | Optional | `0` | Enable Layer 2 TCP blocking |
46
- | **SECURENOW_FIREWALL_IPTABLES** | Optional | `0` | Enable Layer 3 iptables blocking |
47
- | **SECURENOW_FIREWALL_CLOUD** | Optional | - | Cloud WAF provider (cloudflare/aws/gcp) |
48
- | **SECURENOW_TRUSTED_PROXIES** | Optional | - | Trusted proxy IPs for X-Forwarded-For |
49
-
50
- ---
51
-
52
- ## Required Variables
53
-
54
- ### SECURENOW_APPID
55
-
56
- **Description:** Your application identifier. Used as the service name in traces and logs.
57
-
58
- **Format:** String (alphanumeric, hyphens, underscores)
59
-
60
- **Examples:**
61
5
  ```bash
62
- export SECURENOW_APPID=my-express-app
63
- export SECURENOW_APPID=api-gateway
64
- export SECURENOW_APPID=user-service
6
+ npx securenow login
7
+ npx securenow init
65
8
  ```
66
9
 
67
- **Notes:**
68
- - If not set, SecureNow will use a fallback name with UUID
69
- - In cluster mode with `SECURENOW_STRICT=1`, missing APPID will cause process exit
70
- - Alternative: Use `OTEL_SERVICE_NAME` (OpenTelemetry standard)
71
-
72
- **Behavior:**
73
- - Without `SECURENOW_NO_UUID=1`: Service name becomes `{APPID}-{UUID}`
74
- - With `SECURENOW_NO_UUID=1`: Service name is exactly `{APPID}`
10
+ `login` writes the selected app, collector instance, CLI token, and firewall key to `./.securenow/credentials.json`. `init` ensures that file also contains secure defaults and an `_securenow.explanations` block for end users. Keep `.securenow/` in `.gitignore`.
75
11
 
76
- ---
12
+ ## Production Runtime File
77
13
 
78
- ### SECURENOW_INSTANCE
14
+ Production should use the same file structure, but without the CLI OAuth fields. From a logged-in project:
79
15
 
80
- **Description:** Base URL of your OTLP collector endpoint.
81
-
82
- **Format:** URL (http/https)
83
-
84
- **Examples:**
85
16
  ```bash
86
- # Local collector
87
- export SECURENOW_INSTANCE=http://localhost:4318
88
-
89
- # Remote collector
90
- export SECURENOW_INSTANCE=http://collector.example.com:4318
91
-
92
- # HTTPS
93
- export SECURENOW_INSTANCE=https://collector.example.com:4318
17
+ npx securenow credentials runtime --env production
94
18
  ```
95
19
 
96
- **Default:** `https://freetrial.securenow.ai:4318` (if not set)
97
-
98
- **Notes:**
99
- - Used to construct traces and logs endpoints
100
- - Traces sent to: `{SECURENOW_INSTANCE}/v1/traces`
101
- - Logs sent to: `{SECURENOW_INSTANCE}/v1/logs`
102
- - Alternative: Use `OTEL_EXPORTER_OTLP_ENDPOINT`
103
-
104
- ---
20
+ This writes:
105
21
 
106
- ## Service Naming
107
-
108
- ### OTEL_SERVICE_NAME
109
-
110
- **Description:** Standard OpenTelemetry variable for service name. Alternative to `SECURENOW_APPID`.
111
-
112
- **Format:** String
113
-
114
- **Example:**
115
- ```bash
116
- export OTEL_SERVICE_NAME=my-app
22
+ ```text
23
+ .securenow/credentials.production.json
117
24
  ```
118
25
 
119
- **Priority:** If both are set, `OTEL_SERVICE_NAME` takes precedence.
26
+ Deploy that JSON as a secret file and mount or copy it to:
120
27
 
121
- ---
122
-
123
- ### SECURENOW_NO_UUID
124
-
125
- **Description:** Disable automatic UUID suffix on service name.
126
-
127
- **Format:** `1` (enabled) or `0` (disabled)
128
-
129
- **Default:** `0`
130
-
131
- **Example:**
132
- ```bash
133
- export SECURENOW_NO_UUID=1
28
+ ```text
29
+ <app-root>/.securenow/credentials.json
134
30
  ```
135
31
 
136
- **Use case:**
137
- - PM2 cluster mode - use same service name for all workers
138
- - Docker containers with replica sets
139
- - Kubernetes pods in a deployment
140
-
141
- **Behavior:**
142
- - `0`: Service name = `my-app-a1b2c3d4`
143
- - `1`: Service name = `my-app`
144
-
145
- ---
146
-
147
- ### SECURENOW_STRICT
148
-
149
- **Description:** Exit process if `SECURENOW_APPID` is not set in cluster mode.
150
-
151
- **Format:** `1` (enabled) or `0` (disabled)
152
-
153
- **Default:** `0`
154
-
155
- **Example:**
156
- ```bash
157
- export SECURENOW_STRICT=1
158
- ```
159
-
160
- **Use case:**
161
- - Production environments where service name must be explicit
162
- - Prevent "free" or auto-generated service names
163
- - Ensure proper configuration before starting
164
-
165
- **Detection:**
166
- Cluster mode is detected when any of these exist:
167
- - `NODE_APP_INSTANCE` (PM2)
168
- - `pm_id` (PM2)
169
-
170
- ---
171
-
172
- ## Connection Settings
173
-
174
- ### OTEL_EXPORTER_OTLP_ENDPOINT
175
-
176
- **Description:** Standard OpenTelemetry variable for OTLP endpoint. Alternative to `SECURENOW_INSTANCE`.
177
-
178
- **Format:** URL
179
-
180
- **Example:**
181
- ```bash
182
- export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318
183
- ```
184
-
185
- **Priority:** If both are set, `OTEL_EXPORTER_OTLP_ENDPOINT` takes precedence.
186
-
187
- ---
188
-
189
- ### OTEL_EXPORTER_OTLP_TRACES_ENDPOINT
190
-
191
- **Description:** Override the traces endpoint specifically.
192
-
193
- **Format:** Full URL including `/v1/traces`
194
-
195
- **Example:**
196
- ```bash
197
- export OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://traces-collector:4318/v1/traces
198
- ```
199
-
200
- **Use case:**
201
- - Separate collectors for traces and logs
202
- - Different routing for traces
203
-
204
- ---
205
-
206
- ### OTEL_EXPORTER_OTLP_LOGS_ENDPOINT
207
-
208
- **Description:** Override the logs endpoint specifically.
209
-
210
- **Format:** Full URL including `/v1/logs`
211
-
212
- **Example:**
213
- ```bash
214
- export OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://logs-collector:4318/v1/logs
215
- ```
216
-
217
- **Use case:**
218
- - Separate collectors for traces and logs
219
- - Different routing for logs
220
-
221
- ---
222
-
223
- ### OTEL_EXPORTER_OTLP_HEADERS
224
-
225
- **Description:** Headers to include in OTLP export requests.
226
-
227
- **Format:** Comma-separated `key=value` pairs
228
-
229
- **Examples:**
230
- ```bash
231
- # Single header
232
- export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your-api-key"
233
-
234
- # Multiple headers
235
- export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=key123,x-tenant-id=tenant456"
236
-
237
- # Authentication
238
- export OTEL_EXPORTER_OTLP_HEADERS="authorization=Bearer token123"
239
- ```
240
-
241
- **Use case:**
242
- - API authentication
243
- - Multi-tenancy headers
244
- - Custom routing headers
245
-
246
- **Notes:**
247
- - Header names are case-insensitive
248
- - Trailing/leading spaces are trimmed
249
-
250
- ---
251
-
252
- ## Logging
253
-
254
- ### SECURENOW_LOGGING_ENABLED
255
-
256
- **Description:** Enable or disable automatic logging to OTLP backend.
257
-
258
- **Format:** `1` (enabled) or `0` (disabled)
259
-
260
- **Default:** `1` (enabled by default)
261
-
262
- **Examples:**
263
- ```bash
264
- # Enable logging
265
- export SECURENOW_LOGGING_ENABLED=1
266
-
267
- # Disable logging
268
- export SECURENOW_LOGGING_ENABLED=0
269
- ```
32
+ The runtime file contains `apiKey`, `app`, `config`, and `_securenow.explanations`; it intentionally omits `token`, `email`, and `expiresAt`.
270
33
 
271
- **When enabled:**
272
- - Logs are sent to `{SECURENOW_INSTANCE}/v1/logs`
273
- - Console instrumentation can capture logs
274
- - Direct logger API is available
34
+ ## Resolution Order
275
35
 
276
- **When disabled:**
277
- - No logs sent to backend
278
- - `getLogger()` returns `null`
279
- - Console instrumentation shows warning
36
+ 1. Project `./.securenow/credentials.json`
37
+ 2. Global `~/.securenow/credentials.json`
38
+ 3. `package.json#name` where a human-readable fallback label is useful
39
+ 4. Built-in secure default
280
40
 
281
- ---
41
+ Legacy environment variables are fallback-only for existing deployments. New local, CI, Docker, and production setups should use the credentials file.
282
42
 
283
- ## Request Body Capture
43
+ ## Credentials File Shape
284
44
 
285
- ### SECURENOW_CAPTURE_BODY
286
-
287
- **Description:** Enable capture of HTTP request bodies in traces.
288
-
289
- **Format:** `1` (enabled) or `0` (disabled)
290
-
291
- **Default:** `1` (enabled)
292
-
293
- **Example:**
294
- ```bash
295
- # Default is enabled. Use this only to opt out:
296
- export SECURENOW_CAPTURE_BODY=0
297
- ```
298
-
299
- **Supported content types:**
300
- - `application/json`
301
- - `application/x-www-form-urlencoded`
302
- - `application/graphql`
303
-
304
- **Not captured:**
305
- - Bodies larger than `SECURENOW_MAX_BODY_SIZE`
306
-
307
- **Security:**
308
- All captured bodies are automatically scanned for sensitive fields and redacted.
309
-
310
- ---
311
-
312
- ### SECURENOW_MAX_BODY_SIZE
313
-
314
- **Description:** Maximum request body size to capture (in bytes).
315
-
316
- **Format:** Number (bytes)
317
-
318
- **Default:** `10240` (10 KB)
319
-
320
- **Examples:**
321
- ```bash
322
- # 10 KB (default)
323
- export SECURENOW_MAX_BODY_SIZE=10240
324
-
325
- # 20 KB
326
- export SECURENOW_MAX_BODY_SIZE=20480
327
-
328
- # 5 KB
329
- export SECURENOW_MAX_BODY_SIZE=5120
330
- ```
331
-
332
- **Behavior:**
333
- - Bodies larger than this are not captured
334
- - Span attribute shows: `[TOO LARGE: {size} bytes]`
335
-
336
- ---
337
-
338
- ### SECURENOW_SENSITIVE_FIELDS
339
-
340
- **Description:** Additional field names to redact from request bodies (comma-separated).
341
-
342
- **Format:** Comma-separated list of field names
343
-
344
- **Default:** (see below for auto-redacted fields)
345
-
346
- **Examples:**
347
- ```bash
348
- # Additional custom fields
349
- export SECURENOW_SENSITIVE_FIELDS="internal_token,session_key"
350
-
351
- # Multiple fields
352
- export SECURENOW_SENSITIVE_FIELDS="custom_secret,private_data,internal_id"
353
- ```
354
-
355
- **Auto-redacted fields (built-in):**
356
- - `password`, `passwd`, `pwd`
357
- - `secret`, `token`, `api_key`, `apikey`, `access_token`
358
- - `auth`, `credentials`, `mysql_pwd`
359
- - `stripeToken`, `card`, `cardnumber`
360
- - `ccv`, `cvc`, `cvv`
361
- - `ssn`, `pin`
362
-
363
- **Matching:**
364
- - Case-insensitive
365
- - Substring match (e.g., `password` matches `user_password`, `PASSWORD`, `passwordField`)
366
- - Works recursively in nested objects
367
-
368
- ---
369
-
370
- ### SECURENOW_CAPTURE_MULTIPART
371
-
372
- **Description:** Enable capture of `multipart/form-data` request bodies (file upload metadata and text fields). Uses a streaming parser that processes boundary markers on the fly — file binary content is never buffered or stored.
373
-
374
- **Format:** `1` (enabled) or `0` (disabled)
375
-
376
- **Default:** `1` (enabled)
377
-
378
- **Example:**
379
- ```bash
380
- # Default is enabled. Use this only to opt out:
381
- export SECURENOW_CAPTURE_MULTIPART=0
382
- ```
383
-
384
- **What gets captured:**
385
- - **Text fields** — field name and value (up to 1000 characters), with sensitive fields auto-redacted
386
- - **File fields** — metadata only: field name, filename, content-type, and size in bytes (no binary content)
387
-
388
- **Example span attribute (`http.request.body`):**
389
45
  ```json
390
46
  {
391
- "fields": { "description": "My upload", "token": "[REDACTED]" },
392
- "files": [
393
- { "field": "avatar", "filename": "photo.jpg", "contentType": "image/jpeg", "size": 524288 },
394
- { "field": "document", "filename": "report.pdf", "contentType": "application/pdf", "size": 1048576 }
395
- ]
47
+ "apiKey": "snk_live_...",
48
+ "app": {
49
+ "key": "<secure-now-app-uuid>",
50
+ "name": "my-app",
51
+ "instance": "https://freetrial.securenow.ai:4318"
52
+ },
53
+ "config": {
54
+ "logging": { "enabled": true },
55
+ "capture": {
56
+ "body": true,
57
+ "multipart": true,
58
+ "maxBodySize": 10240,
59
+ "sensitiveFields": []
60
+ },
61
+ "otel": {
62
+ "endpoint": null,
63
+ "tracesEndpoint": null,
64
+ "logsEndpoint": null,
65
+ "headers": {},
66
+ "logLevel": "none",
67
+ "disableInstrumentations": []
68
+ },
69
+ "runtime": {
70
+ "deploymentEnvironment": "production",
71
+ "noUuid": null,
72
+ "strict": false,
73
+ "testSpan": false,
74
+ "hideBanner": false
75
+ },
76
+ "firewall": {
77
+ "enabled": true,
78
+ "apiUrl": "https://api.securenow.ai",
79
+ "versionCheckInterval": 10,
80
+ "syncInterval": 300,
81
+ "failMode": "open",
82
+ "statusCode": 403,
83
+ "log": true,
84
+ "tcp": false,
85
+ "iptables": false,
86
+ "cloud": null,
87
+ "cloudDryRun": false,
88
+ "cloudflare": {
89
+ "apiToken": null,
90
+ "accountId": null
91
+ },
92
+ "aws": {
93
+ "wafIpSetId": null,
94
+ "wafIpSetName": "securenow-blocklist",
95
+ "wafScope": "REGIONAL"
96
+ },
97
+ "gcp": {
98
+ "projectId": null,
99
+ "securityPolicy": null
100
+ }
101
+ },
102
+ "networking": {
103
+ "trustedProxies": []
104
+ }
105
+ }
396
106
  }
397
107
  ```
398
108
 
399
- **Additional span attributes set:**
400
- - `http.request.body.type` = `"multipart"`
401
- - `http.request.body.size` total raw request body size in bytes
402
- - `http.request.body.fields_count` — number of text fields
403
- - `http.request.body.files_count` number of file fields
404
-
405
- **Memory:** Bounded at ~few KB regardless of upload size (streaming parser discards file content as it passes through).
406
-
407
- **Parts limit:** 100 parts maximum per request (safety guard).
408
-
409
- **Relationship to body capture:** multipart metadata capture has its own opt-out flag. Leave `SECURENOW_CAPTURE_MULTIPART` unset, `1`, or `true` to keep it enabled.
410
-
411
- **Since:** v5.8.0
412
-
413
- ---
414
-
415
- ## Instrumentation Control
416
-
417
- ### SECURENOW_DISABLE_INSTRUMENTATIONS
418
-
419
- **Description:** Disable specific OpenTelemetry instrumentations.
420
-
421
- **Format:** Comma-separated list of package names
422
-
423
- **Example:**
424
- ```bash
425
- # Disable file system and DNS instrumentations
426
- export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns
427
-
428
- # Disable multiple
429
- export SECURENOW_DISABLE_INSTRUMENTATIONS=fs,dns,net,http2
430
- ```
431
-
432
- **Common packages you might disable:**
433
- - `fs` - File system operations
434
- - `dns` - DNS lookups
435
- - `net` - Network operations
436
- - `http2` - HTTP/2 client/server
437
- - `grpc` - gRPC client/server
438
-
439
- **Use case:**
440
- - Reduce overhead by disabling unused instrumentations
441
- - Avoid noisy traces from certain operations
442
- - Debug issues with specific instrumentations
443
-
444
- ---
445
-
446
- ## Debugging
447
-
448
- ### OTEL_LOG_LEVEL
449
-
450
- **Description:** OpenTelemetry SDK internal log level.
451
-
452
- **Format:** `none`, `error`, `warn`, `info`, `debug`
453
-
454
- **Default:** `none`
455
-
456
- **Examples:**
457
- ```bash
458
- # See all debug information
459
- export OTEL_LOG_LEVEL=debug
460
-
461
- # Only errors
462
- export OTEL_LOG_LEVEL=error
463
-
464
- # No SDK logs
465
- export OTEL_LOG_LEVEL=none
466
- ```
467
-
468
- **Use case:**
469
- - Troubleshooting setup issues
470
- - Understanding trace/log export behavior
471
- - Debugging connection problems
472
-
473
- **Output:**
474
- - Goes to console (stderr)
475
- - Prefixed with `[securenow]`
476
-
477
- ---
478
-
479
- ### SECURENOW_TEST_SPAN
480
-
481
- **Description:** Emit a test span on startup to verify tracing is working.
482
-
483
- **Format:** `1` (enabled) or `0` (disabled)
484
-
485
- **Default:** `0`
486
-
487
- **Example:**
488
- ```bash
489
- export SECURENOW_TEST_SPAN=1
490
- ```
491
-
492
- **Behavior:**
493
- - Creates a span named `securenow.startup.smoke`
494
- - Span is immediately ended
495
- - Useful for testing collector connectivity
496
-
497
- ---
498
-
499
- ## Environment
500
-
501
- ### NODE_ENV
502
-
503
- **Description:** Standard Node.js environment variable. Sent as `deployment.environment` attribute.
504
-
505
- **Format:** String (typically: `development`, `production`, `test`, `staging`)
506
-
507
- **Default:** `production`
109
+ ## Credentials Keys
110
+
111
+ | Credentials path | Default | Notes |
112
+ |---|---|---|
113
+ | `app.key` | package name fallback | SecureNow app routing UUID / OTel service name. |
114
+ | `app.name` | package name fallback | Human-readable app name. |
115
+ | `app.instance` | `https://freetrial.securenow.ai:4318` | OTLP base endpoint. |
116
+ | `apiKey` | `null` | `snk_live_...` firewall sync key. |
117
+ | `config.otel.endpoint` | app instance | Optional OTLP base endpoint override. |
118
+ | `config.otel.tracesEndpoint` | `{instance}/v1/traces` | Full traces endpoint. |
119
+ | `config.otel.logsEndpoint` | `{instance}/v1/logs` | Full logs endpoint. |
120
+ | `config.otel.headers` | auto `x-api-key=<app.key>` | Extra OTLP headers as an object. |
121
+ | `config.otel.logLevel` | `none` | `none`, `error`, `warn`, `info`, or `debug`. |
122
+ | `config.otel.disableInstrumentations` | `[]` | OTel instrumentation package names to skip. |
123
+ | `config.logging.enabled` | `true` | Console log forwarding. |
124
+ | `config.capture.body` | `true` | JSON, GraphQL, and form body capture. |
125
+ | `config.capture.multipart` | `true` | Multipart text fields and file metadata; never file content. |
126
+ | `config.capture.maxBodySize` | `10240` | Bytes captured per request body. |
127
+ | `config.capture.sensitiveFields` | `[]` | Extra redaction field fragments. |
128
+ | `config.runtime.deploymentEnvironment` | `production` | Sent as `deployment.environment`. |
129
+ | `config.runtime.noUuid` | auto | Auto is true when an app key is present. |
130
+ | `config.runtime.strict` | `false` | Exit clustered workers when no app identity resolves. |
131
+ | `config.runtime.testSpan` | `false` | Prefer `npx securenow test-span` for manual checks. |
132
+ | `config.runtime.hideBanner` | `false` | Hide free-trial response banner. |
133
+ | `config.firewall.enabled` | `true` | Local kill-switch; dashboard app toggle also applies. |
134
+ | `config.firewall.apiUrl` | `https://api.securenow.ai` | SecureNow API base URL. |
135
+ | `config.firewall.versionCheckInterval` | `10` | Seconds between lightweight version checks. |
136
+ | `config.firewall.syncInterval` | `300` | Seconds between full blocklist syncs. |
137
+ | `config.firewall.failMode` | `open` | `open` or `closed`. |
138
+ | `config.firewall.statusCode` | `403` | HTTP status for blocked requests. |
139
+ | `config.firewall.log` | `true` | Log firewall decisions locally. |
140
+ | `config.firewall.tcp` | `false` | Opt-in Layer 2 TCP drop. |
141
+ | `config.firewall.iptables` | `false` | Opt-in Linux iptables/nftables drop. |
142
+ | `config.firewall.cloud` | `null` | `cloudflare`, `aws`, or `gcp`. |
143
+ | `config.firewall.cloudDryRun` | `false` | Preview cloud WAF pushes. |
144
+ | `config.firewall.cloudflare.apiToken` | `null` | Cloudflare Layer 4 WAF credential. |
145
+ | `config.firewall.cloudflare.accountId` | `null` | Cloudflare account id. |
146
+ | `config.firewall.aws.wafIpSetId` | `null` | AWS WAF IP set id. |
147
+ | `config.firewall.aws.wafIpSetName` | `securenow-blocklist` | AWS WAF IP set name. |
148
+ | `config.firewall.aws.wafScope` | `REGIONAL` | AWS WAF scope. |
149
+ | `config.firewall.gcp.projectId` | `null` | GCP project id. |
150
+ | `config.firewall.gcp.securityPolicy` | `null` | GCP Cloud Armor policy. |
151
+ | `config.networking.trustedProxies` | `[]` | Additional proxy IPs trusted for `X-Forwarded-For`. |
152
+
153
+ ## Common Edits
508
154
 
509
- **Examples:**
510
- ```bash
511
- export NODE_ENV=development
512
- export NODE_ENV=production
513
- export NODE_ENV=staging
514
- export NODE_ENV=test
515
- ```
516
-
517
- **Use case:**
518
- - Filter traces/logs by environment
519
- - Different configurations per environment
520
- - Standard Node.js convention
521
-
522
- ---
523
-
524
- ## Firewall (IP Blocking)
525
-
526
- ### SECURENOW_API_KEY
527
-
528
- **Description:** API key for the SecureNow firewall. When set, the firewall auto-activates and syncs your blocklist. Must have the `firewall:read` scope.
529
-
530
- **Format:** String (`snk_live_` prefix + 64 hex characters)
531
-
532
- **Example:**
533
- ```bash
534
- export SECURENOW_API_KEY=snk_live_a1b2c3d4e5f6...
535
- ```
536
-
537
- **v7.4.0+:** the firewall also reads this key from `.securenow/credentials.json` (written by `securenow login`, which enables the selected app firewall by default, or by `securenow api-key set`). The env var only wins if it starts with `snk_live_` — otherwise the credentials file is used, so you can rely on the file for local dev without unsetting any stray env var. Setting an app UUID here (the old pre-7.1 habit) is ignored for firewall auth and would produce silent 401s; always use a `snk_live_...` key.
538
-
539
- ---
540
-
541
- ### SECURENOW_API_URL
542
-
543
- **Description:** Base URL for the SecureNow API.
544
-
545
- **Format:** URL
546
-
547
- **Default:** `https://api.securenow.ai`
548
-
549
- **Example:**
550
- ```bash
551
- export SECURENOW_API_URL=https://api.securenow.ai
552
- ```
553
-
554
- ---
555
-
556
- ### SECURENOW_FIREWALL_ENABLED
557
-
558
- **Description:** Master kill-switch for the firewall. Set to `0` to disable even when `SECURENOW_API_KEY` is set.
559
-
560
- **Format:** `1` (enabled) or `0` (disabled)
561
-
562
- **Default:** `1`
563
-
564
- ---
565
-
566
- ### SECURENOW_FIREWALL_SYNC_INTERVAL
567
-
568
- **Description:** How often (in seconds) to refresh the blocklist from the API.
569
-
570
- **Format:** Number (seconds)
571
-
572
- **Default:** `60`
573
-
574
- **Example:**
575
- ```bash
576
- export SECURENOW_FIREWALL_SYNC_INTERVAL=30
577
- ```
578
-
579
- ---
580
-
581
- ### SECURENOW_FIREWALL_FAIL_MODE
582
-
583
- **Description:** Behavior when the blocklist cannot be fetched from the API.
584
-
585
- **Format:** `open` or `closed`
586
-
587
- **Default:** `open`
588
-
589
- - `open` — Allow all traffic when list is unavailable (recommended for most apps)
590
- - `closed` — Block all traffic when list is unavailable (high-security environments)
591
-
592
- ---
593
-
594
- ### SECURENOW_FIREWALL_STATUS_CODE
595
-
596
- **Description:** HTTP status code returned to blocked requests (Layer 1 only).
597
-
598
- **Format:** Number
599
-
600
- **Default:** `403`
601
-
602
- **Example:**
603
- ```bash
604
- export SECURENOW_FIREWALL_STATUS_CODE=429
605
- ```
606
-
607
- ---
608
-
609
- ### SECURENOW_FIREWALL_LOG
610
-
611
- **Description:** Log blocked requests to the console.
612
-
613
- **Format:** `1` (enabled) or `0` (disabled)
614
-
615
- **Default:** `1`
616
-
617
- ---
618
-
619
- ### SECURENOW_FIREWALL_TCP
620
-
621
- **Description:** Enable Layer 2 TCP-level blocking. Destroys sockets from blocked IPs before HTTP parsing starts.
622
-
623
- **Format:** `1` (enabled) or `0` (disabled)
624
-
625
- **Default:** `0`
626
-
627
- **Notes:**
628
- - Only sees direct connection IP (no proxy headers)
629
- - Connections from trusted proxies are passed to Layer 1
630
- - Most effective for direct-to-server deployments
631
-
632
- ---
633
-
634
- ### SECURENOW_FIREWALL_IPTABLES
635
-
636
- **Description:** Enable Layer 3 OS firewall blocking via iptables/nftables. Kernel-level DROP — packets never reach Node.js.
637
-
638
- **Format:** `1` (enabled) or `0` (disabled)
639
-
640
- **Default:** `0`
641
-
642
- **Notes:**
643
- - Linux only (skips gracefully on macOS/Windows)
644
- - Requires root or CAP_NET_ADMIN
645
- - Auto-detects nftables vs iptables
646
- - Dedicated chain: `SECURENOW_BLOCK`
647
-
648
- ---
649
-
650
- ### SECURENOW_FIREWALL_CLOUD
651
-
652
- **Description:** Enable Layer 4 cloud/edge WAF blocking. Pushes the blocklist to your cloud provider's WAF.
653
-
654
- **Format:** `cloudflare`, `aws`, or `gcp`
655
-
656
- **Default:** *(none — disabled)*
657
-
658
- **Provider-specific variables:**
659
-
660
- | Provider | Required Variables |
661
- |----------|-------------------|
662
- | `cloudflare` | `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` |
663
- | `aws` | `AWS_WAF_IP_SET_ID`, standard AWS credentials |
664
- | `gcp` | `GCP_PROJECT_ID`, `GCP_SECURITY_POLICY` |
665
-
666
- ---
667
-
668
- ### SECURENOW_FIREWALL_CLOUD_DRY_RUN
669
-
670
- **Description:** Log cloud WAF pushes without actually applying them. Useful for testing.
671
-
672
- **Format:** `1` (enabled) or `0` (disabled)
673
-
674
- **Default:** `0`
675
-
676
- ---
677
-
678
- ### SECURENOW_TRUSTED_PROXIES
679
-
680
- **Description:** Comma-separated list of additional trusted proxy IPs. The firewall only reads `X-Forwarded-For` from trusted proxies. Private/loopback IPs are always trusted.
681
-
682
- **Format:** Comma-separated IPs
683
-
684
- **Example:**
685
- ```bash
686
- export SECURENOW_TRUSTED_PROXIES=34.120.0.1,34.120.0.2
687
- ```
688
-
689
- ---
690
-
691
- ## Configuration Examples
692
-
693
- ### Development Environment
694
-
695
- ```bash
696
- # .env.development
697
- SECURENOW_APPID=my-app-dev
698
- SECURENOW_INSTANCE=http://localhost:4318
699
- SECURENOW_LOGGING_ENABLED=1
700
- SECURENOW_CAPTURE_BODY=1
701
- SECURENOW_MAX_BODY_SIZE=20480
702
- OTEL_LOG_LEVEL=debug
703
- SECURENOW_TEST_SPAN=1
704
- NODE_ENV=development
705
- ```
706
-
707
- ### Production Environment
708
-
709
- ```bash
710
- # .env.production
711
- SECURENOW_APPID=my-app-prod
712
- SECURENOW_INSTANCE=https://collector.prod.example.com:4318
713
- OTEL_EXPORTER_OTLP_HEADERS=x-api-key=prod-key-12345
714
- SECURENOW_LOGGING_ENABLED=1
715
- SECURENOW_CAPTURE_BODY=0
716
- SECURENOW_NO_UUID=1
717
- SECURENOW_STRICT=1
718
- SECURENOW_SENSITIVE_FIELDS=internal_id,session_token
719
- OTEL_LOG_LEVEL=error
720
- NODE_ENV=production
721
-
722
- # Firewall (optional — auto-activates when API key is set)
723
- SECURENOW_API_KEY=snk_live_abc123...
724
- SECURENOW_FIREWALL_TCP=1
725
- SECURENOW_FIREWALL_SYNC_INTERVAL=30
726
- ```
727
-
728
- ### PM2 Cluster
729
-
730
- ```bash
731
- # ecosystem.config.js environment
732
- SECURENOW_APPID=my-app
733
- SECURENOW_INSTANCE=http://localhost:4318
734
- SECURENOW_LOGGING_ENABLED=1
735
- SECURENOW_NO_UUID=1
736
- SECURENOW_STRICT=1
737
- SECURENOW_CAPTURE_BODY=1
738
- NODE_ENV=production
739
- ```
740
-
741
- ### Docker / Kubernetes
742
-
743
- ```bash
744
- # Docker environment or K8s ConfigMap
745
- SECURENOW_APPID=my-service
746
- SECURENOW_INSTANCE=http://otel-collector:4318
747
- SECURENOW_LOGGING_ENABLED=1
748
- SECURENOW_NO_UUID=1
749
- SECURENOW_CAPTURE_BODY=0
750
- NODE_ENV=production
751
- ```
752
-
753
- ### Separate Collectors for Traces and Logs
754
-
755
- ```bash
756
- # Different backends for traces and logs
757
- SECURENOW_APPID=my-app
758
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://traces-collector:4318/v1/traces
759
- OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://logs-collector:4318/v1/logs
760
- SECURENOW_LOGGING_ENABLED=1
761
- ```
762
-
763
- ---
764
-
765
- ## Priority and Overrides
766
-
767
- When multiple variables are set, this is the priority order:
768
-
769
- ### Service Name
770
-
771
- 1. `OTEL_SERVICE_NAME` (highest priority)
772
- 2. `SECURENOW_APPID`
773
- 3. Auto-generated fallback (lowest priority)
774
-
775
- ### OTLP Endpoint
776
-
777
- 1. `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` (for traces)
778
- 2. `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` (for logs)
779
- 3. `OTEL_EXPORTER_OTLP_ENDPOINT`
780
- 4. `SECURENOW_INSTANCE`
781
- 5. Default: `https://freetrial.securenow.ai:4318` (lowest priority)
782
-
783
- ---
784
-
785
- ## Validation
786
-
787
- SecureNow validates environment variables on startup. Check console output:
788
-
789
- ```bash
790
- [securenow] pid=12345 SECURENOW_APPID="my-app" OTEL_SERVICE_NAME=null → service.name=my-app-uuid123
791
- [securenow] OTel SDK started → http://localhost:4318/v1/traces
792
- [securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
793
- [securenow] 📝 Request body capture: ENABLED (max: 10240 bytes)
794
- ```
795
-
796
- ---
797
-
798
- ## Best Practices
799
-
800
- ### 1. Use .env Files
801
-
802
- Don't hardcode in your application:
803
-
804
- ```bash
805
- # .env
806
- SECURENOW_APPID=my-app
807
- SECURENOW_INSTANCE=http://localhost:4318
808
- ```
809
-
810
- ### 2. Different Configs per Environment
811
-
812
- ```bash
813
- # .env.development
814
- SECURENOW_CAPTURE_BODY=1
815
- OTEL_LOG_LEVEL=debug
816
-
817
- # .env.production
818
- SECURENOW_CAPTURE_BODY=0
819
- OTEL_LOG_LEVEL=error
820
- ```
821
-
822
- ### 3. Use SECURENOW_NO_UUID in Clusters
823
-
824
- ```bash
825
- # PM2 cluster with 4 workers
826
- SECURENOW_NO_UUID=1
827
- ```
828
-
829
- ### 4. Enable SECURENOW_STRICT in Production
830
-
831
- ```bash
832
- # Fail fast if misconfigured
833
- SECURENOW_STRICT=1
834
- ```
835
-
836
- ### 5. Disable Body Capture in Production
837
-
838
- ```bash
839
- # Development
840
- SECURENOW_CAPTURE_BODY=1
841
-
842
- # Production
843
- SECURENOW_CAPTURE_BODY=0
844
- ```
845
-
846
- ---
847
-
848
- ## Troubleshooting
849
-
850
- ### Check Current Values
851
-
852
- ```bash
853
- # Print all SECURENOW variables
854
- env | grep SECURENOW
855
-
856
- # Print all OTEL variables
857
- env | grep OTEL
858
-
859
- # Check specific variable
860
- echo $SECURENOW_APPID
861
- ```
862
-
863
- ### Verify in Application
864
-
865
- SecureNow logs current configuration on startup. Look for lines like:
866
-
867
- ```
868
- [securenow] pid=12345 SECURENOW_APPID="my-app" → service.name=my-app
869
- [securenow] OTel SDK started → http://localhost:4318/v1/traces
870
- ```
871
-
872
- ### Enable Debug Mode
873
-
874
- ```bash
875
- export OTEL_LOG_LEVEL=debug
876
- node app.js
155
+ ```json
156
+ {
157
+ "config": {
158
+ "capture": {
159
+ "maxBodySize": 20480,
160
+ "sensitiveFields": ["session_id", "internal_token"]
161
+ },
162
+ "logging": { "enabled": false },
163
+ "firewall": { "failMode": "closed" }
164
+ }
165
+ }
877
166
  ```
878
-
879
- ---
880
-
881
- ## Related Documentation
882
-
883
- - [Firewall Guide](./FIREWALL-GUIDE.md)
884
- - [API Keys Guide](./API-KEYS-GUIDE.md)
885
- - [Express Setup Guide](./EXPRESS-SETUP-GUIDE.md)
886
- - [Next.js Setup Guide](./NEXTJS-SETUP-COMPLETE.md)
887
- - [Logging Guide](./LOGGING-GUIDE.md)
888
- - [NPM README](../NPM_README.md)
889
-
890
- ---
891
-
892
- **Complete reference for all SecureNow environment variables.** 🎯