securenow 5.18.0 → 6.0.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 (85) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +40 -239
  3. package/cli.js +455 -415
  4. package/console-instrumentation.js +136 -147
  5. package/docs/ALL-FRAMEWORKS-QUICKSTART.md +455 -1339
  6. package/docs/ARCHITECTURE.md +3 -3
  7. package/docs/AUTO-BODY-CAPTURE.md +1 -1
  8. package/docs/AUTO-SETUP.md +4 -4
  9. package/docs/AUTOMATIC-IP-CAPTURE.md +5 -5
  10. package/docs/BODY-CAPTURE-QUICKSTART.md +2 -2
  11. package/docs/CHANGELOG-NEXTJS.md +35 -1
  12. package/docs/CUSTOMER-GUIDE.md +16 -16
  13. package/docs/EASIEST-SETUP.md +5 -5
  14. package/docs/ENVIRONMENT-VARIABLES.md +652 -880
  15. package/docs/EXPRESS-BODY-CAPTURE.md +12 -13
  16. package/docs/EXPRESS-SETUP-GUIDE.md +720 -719
  17. package/docs/INDEX.md +4 -22
  18. package/docs/LOGGING-GUIDE.md +708 -701
  19. package/docs/LOGGING-QUICKSTART.md +255 -234
  20. package/docs/NEXTJS-BODY-CAPTURE.md +2 -2
  21. package/docs/NEXTJS-GUIDE.md +14 -14
  22. package/docs/NEXTJS-QUICKSTART.md +1 -1
  23. package/docs/NEXTJS-WRAPPER-APPROACH.md +1 -1
  24. package/docs/QUICKSTART-BODY-CAPTURE.md +2 -2
  25. package/docs/REDACTION-EXAMPLES.md +1 -1
  26. package/docs/REQUEST-BODY-CAPTURE.md +10 -19
  27. package/docs/VERCEL-OTEL-MIGRATION.md +3 -3
  28. package/examples/README.md +6 -6
  29. package/examples/instrumentation-with-auto-capture.ts +1 -1
  30. package/examples/nextjs-env-example.txt +2 -2
  31. package/examples/nextjs-instrumentation.js +1 -1
  32. package/examples/nextjs-instrumentation.ts +1 -1
  33. package/examples/nextjs-with-logging-example.md +6 -6
  34. package/examples/nextjs-with-options.ts +1 -1
  35. package/examples/test-nextjs-setup.js +1 -1
  36. package/nextjs-auto-capture.js +207 -199
  37. package/nextjs-middleware.js +181 -186
  38. package/nextjs-webpack-config.js +53 -88
  39. package/nextjs-wrapper.js +158 -158
  40. package/nextjs.d.ts +1 -1
  41. package/nextjs.js +198 -186
  42. package/package.json +45 -67
  43. package/postinstall.js +6 -6
  44. package/register.d.ts +1 -1
  45. package/register.js +4 -39
  46. package/tracing.d.ts +1 -2
  47. package/tracing.js +26 -286
  48. package/web-vite.mjs +156 -239
  49. package/CONSUMING-APPS-GUIDE.md +0 -455
  50. package/NPM_README.md +0 -1933
  51. package/SKILL-API.md +0 -600
  52. package/SKILL-CLI.md +0 -409
  53. package/cidr.js +0 -83
  54. package/cli/apps.js +0 -585
  55. package/cli/auth.js +0 -280
  56. package/cli/client.js +0 -115
  57. package/cli/config.js +0 -173
  58. package/cli/firewall.js +0 -100
  59. package/cli/fp.js +0 -638
  60. package/cli/init.js +0 -201
  61. package/cli/monitor.js +0 -440
  62. package/cli/run.js +0 -133
  63. package/cli/security.js +0 -1064
  64. package/cli/ui.js +0 -386
  65. package/docs/API-KEYS-GUIDE.md +0 -233
  66. package/docs/AUTO-SETUP-SUMMARY.md +0 -331
  67. package/docs/BODY-CAPTURE-FIX.md +0 -261
  68. package/docs/COMPLETION-REPORT.md +0 -408
  69. package/docs/FINAL-SOLUTION.md +0 -335
  70. package/docs/FIREWALL-GUIDE.md +0 -426
  71. package/docs/IMPLEMENTATION-SUMMARY.md +0 -410
  72. package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +0 -323
  73. package/docs/NEXTJS-SETUP-COMPLETE.md +0 -795
  74. package/docs/NUXT-GUIDE.md +0 -166
  75. package/docs/SOLUTION-SUMMARY.md +0 -312
  76. package/firewall-cloud.js +0 -212
  77. package/firewall-iptables.js +0 -139
  78. package/firewall-only.js +0 -38
  79. package/firewall-tcp.js +0 -74
  80. package/firewall.js +0 -720
  81. package/free-trial-banner.js +0 -174
  82. package/nuxt-server-plugin.mjs +0 -423
  83. package/nuxt.d.ts +0 -60
  84. package/nuxt.mjs +0 -75
  85. package/resolve-ip.js +0 -77
package/SKILL-API.md DELETED
@@ -1,600 +0,0 @@
1
- # SecureNow SDK — Agent Skill
2
-
3
- Instrument any Node.js application with OpenTelemetry tracing, structured logging, request body capture, and a multi-layer IP firewall. Supports Express, Fastify, NestJS, Koa, Hapi, Next.js, Nuxt 3, Vite (browser), and raw `http.createServer` — with zero code changes for most setups.
4
-
5
- ## Installation
6
-
7
- ```bash
8
- npm install securenow
9
- ```
10
-
11
- ### Install This Skill in Cursor
12
-
13
- Save this file as `.cursor/skills/securenow-api/SKILL.md` in your project. Your AI agent will auto-discover it whenever you ask about integrating securenow, configuring tracing, setting up the firewall, or instrumenting any framework.
14
-
15
- ## Quick Start — Any Node.js Framework
16
-
17
- ### 1. Set Environment Variables
18
-
19
- ```bash
20
- # .env or .env.local
21
- SECURENOW_APPID=my-app
22
- SECURENOW_INSTANCE=https://your-collector:4318
23
- ```
24
-
25
- ### 2. Run With Instrumentation
26
-
27
- **Option A — CLI (recommended):**
28
-
29
- ```bash
30
- npx securenow run src/index.js
31
- ```
32
-
33
- **Option B — Node preload flag:**
34
-
35
- ```bash
36
- node -r securenow/register src/index.js
37
- ```
38
-
39
- **Option C — Auto-setup for Next.js:**
40
-
41
- ```bash
42
- npx securenow init --key snk_live_...
43
- ```
44
-
45
- That's it. Traces and logs flow to your OTLP collector. No code changes for Express, Fastify, NestJS, Koa, Hapi, and raw Node.
46
-
47
- ### 3. Enable the Firewall (Optional)
48
-
49
- Add one more env var to auto-activate IP blocking:
50
-
51
- ```bash
52
- SECURENOW_API_KEY=snk_live_abc123...
53
- ```
54
-
55
- The firewall syncs your blocklist and enforces it on every request — zero code changes.
56
-
57
- ---
58
-
59
- ## Import Map
60
-
61
- | Import | Purpose | Type |
62
- |--------|---------|------|
63
- | `securenow` / `securenow/register` | Auto-register tracing + firewall (side-effect) | Preload (`-r`) |
64
- | `securenow/tracing` | Core OTel SDK; exports `getLogger()`, `isLoggingEnabled()` | CJS |
65
- | `securenow/nextjs` | Next.js instrumentation; exports `registerSecureNow(options?)` | CJS |
66
- | `securenow/nextjs-webpack-config` | Next.js config wrapper; exports `withSecureNow()`, `getSecureNowWebpackConfig()`, `EXTERNAL_PACKAGES` | CJS |
67
- | `securenow/nextjs-middleware` | Edge middleware body capture; exports `middleware()`, `redactSensitiveData()`, `DEFAULT_SENSITIVE_FIELDS` | CJS |
68
- | `securenow/nextjs-wrapper` | Route handler wrappers; exports `withSecureNow()`, `withSecureNowAsync()`, `captureRequestBody()`, `redactSensitiveData()` | CJS |
69
- | `securenow/nextjs-auto-capture` | Auto-patch Next request for body capture; exports `patchNextRequest()`, `safeBodyCapture()`, `redactSensitiveData()`, `isBodyCaptureEnabled()` | CJS |
70
- | `securenow/nuxt` | Nuxt 3 module (add to `modules` array) | ESM |
71
- | `securenow/firewall` | Standalone firewall; exports `init()`, `shutdown()`, `getStats()`, `getMatcher()`, `getAllowlistMatcher()` | CJS |
72
- | `securenow/firewall-only` | Preload: dotenv + firewall only, no tracing | Preload (`-r`) |
73
- | `securenow/cidr` | CIDR utilities; exports `createMatcher()`, `ipToInt()`, `parseCidr()`, `matchesCidr()` | CJS |
74
- | `securenow/resolve-ip` | IP resolution; exports `resolveClientIp()`, `resolveSocketIp()`, `isFromTrustedProxy()` | CJS |
75
- | `securenow/console-instrumentation` | Console→OTLP bridge; exports `originalConsole`, `restoreConsole()` | CJS |
76
- | `securenow/web-vite` | Browser OTel (document load, fetch, XHR, user interaction); default export `startSecurenowWeb()` | ESM |
77
- | `securenow/register-vite` | CJS bridge for Vite preload | CJS |
78
-
79
- ---
80
-
81
- ## Framework Integration Guides
82
-
83
- ### Express / Fastify / NestJS / Koa / Hapi / Raw Node
84
-
85
- No code changes. Use the preload:
86
-
87
- ```bash
88
- node -r securenow/register app.js
89
- ```
90
-
91
- Or with the CLI:
92
-
93
- ```bash
94
- npx securenow run app.js
95
- ```
96
-
97
- **PM2:**
98
-
99
- ```javascript
100
- // ecosystem.config.cjs
101
- module.exports = {
102
- apps: [{
103
- name: 'my-app',
104
- script: './app.js',
105
- instances: 4,
106
- node_args: '-r securenow/register',
107
- env: {
108
- SECURENOW_APPID: 'my-app',
109
- SECURENOW_INSTANCE: 'https://your-collector:4318',
110
- SECURENOW_NO_UUID: '1',
111
- },
112
- }],
113
- };
114
- ```
115
-
116
- **Docker:**
117
-
118
- ```dockerfile
119
- ENV SECURENOW_APPID=my-app
120
- ENV SECURENOW_INSTANCE=https://your-collector:4318
121
- CMD ["node", "-r", "securenow/register", "app.js"]
122
- ```
123
-
124
- ---
125
-
126
- ### Next.js
127
-
128
- Three files to touch:
129
-
130
- **1. `next.config.js`** (or `.mjs` / `.ts`):
131
-
132
- ```javascript
133
- const { withSecureNow } = require('securenow/nextjs-webpack-config');
134
-
135
- module.exports = withSecureNow({
136
- // your existing config
137
- });
138
- ```
139
-
140
- `withSecureNow()` auto-detects Next.js version:
141
- - **>=15**: sets `serverExternalPackages`
142
- - **<15**: sets `experimental.serverComponentsExternalPackages` + `experimental.instrumentationHook` + webpack ignore rules
143
-
144
- **2. `instrumentation.ts`** (or `.js`, can be in `src/`):
145
-
146
- ```typescript
147
- export async function register() {
148
- if (process.env.NEXT_RUNTIME === 'nodejs') {
149
- const { registerSecureNow } = require('securenow/nextjs');
150
- registerSecureNow();
151
- }
152
- }
153
- ```
154
-
155
- `registerSecureNow(options?)` accepts:
156
-
157
- ```typescript
158
- interface RegisterOptions {
159
- serviceName?: string; // override SECURENOW_APPID
160
- endpoint?: string; // override SECURENOW_INSTANCE
161
- noUuid?: boolean; // override SECURENOW_NO_UUID
162
- captureBody?: boolean; // override SECURENOW_CAPTURE_BODY
163
- }
164
- ```
165
-
166
- On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-node`.
167
-
168
- **3. `.env.local`:**
169
-
170
- ```bash
171
- SECURENOW_APPID=my-nextjs-app
172
- SECURENOW_INSTANCE=https://your-collector:4318
173
- ```
174
-
175
- #### Next.js Body Capture
176
-
177
- **Option A — Auto-capture (recommended):**
178
-
179
- Add to your `instrumentation.ts`:
180
-
181
- ```typescript
182
- export async function register() {
183
- if (process.env.NEXT_RUNTIME === 'nodejs') {
184
- const { registerSecureNow } = require('securenow/nextjs');
185
- registerSecureNow({ captureBody: true });
186
- require('securenow/nextjs-auto-capture');
187
- }
188
- }
189
- ```
190
-
191
- **Option B — Middleware:**
192
-
193
- ```typescript
194
- // middleware.ts
195
- export { middleware } from 'securenow/nextjs-middleware';
196
- export const config = { matcher: ['/api/:path*'] };
197
- ```
198
-
199
- **Option C — Per-route wrapper:**
200
-
201
- ```typescript
202
- import { withSecureNow } from 'securenow/nextjs-wrapper';
203
-
204
- export const POST = withSecureNow(async (req) => {
205
- // handler
206
- });
207
- ```
208
-
209
- #### Next.js with `securenow init`
210
-
211
- ```bash
212
- npx securenow init --key snk_live_abc123...
213
- ```
214
-
215
- Auto-detects Next.js, creates `instrumentation.ts`, suggests `next.config` changes, writes API key to `.env.local`.
216
-
217
- ---
218
-
219
- ### Nuxt 3
220
-
221
- **`nuxt.config.ts`:**
222
-
223
- ```typescript
224
- export default defineNuxtConfig({
225
- modules: ['securenow/nuxt'],
226
- securenow: {
227
- // optional overrides (defaults come from env vars)
228
- },
229
- });
230
- ```
231
-
232
- **`.env`:**
233
-
234
- ```bash
235
- SECURENOW_APPID=my-nuxt-app
236
- SECURENOW_INSTANCE=https://your-collector:4318
237
- ```
238
-
239
- The Nuxt module auto-configures Nitro externals, runtime config, and a server plugin that sets up OTel tracing + logging + firewall.
240
-
241
- ---
242
-
243
- ### Vite / Browser
244
-
245
- ```javascript
246
- import startSecurenowWeb from 'securenow/web-vite';
247
-
248
- startSecurenowWeb({
249
- serviceName: 'my-frontend',
250
- endpoint: 'https://your-collector:4318',
251
- });
252
- ```
253
-
254
- Instruments document load, fetch, XMLHttpRequest, and user interactions with browser-side OpenTelemetry.
255
-
256
- ---
257
-
258
- ## Firewall — Multi-Layer IP Blocking
259
-
260
- The firewall auto-activates when `SECURENOW_API_KEY` is set. It syncs your blocklist from the SecureNow API and enforces it across up to four layers:
261
-
262
- ```
263
- Layer 4: Cloud/Edge WAF → blocked at CDN (Cloudflare, AWS WAF, GCP Cloud Armor)
264
- Layer 3: OS Firewall → kernel-level DROP (iptables/nftables)
265
- Layer 2: TCP Socket → socket.destroy() before HTTP parsing
266
- Layer 1: HTTP Handler → 403 JSON response (always active)
267
- ```
268
-
269
- ### Activate
270
-
271
- ```bash
272
- # .env
273
- SECURENOW_API_KEY=snk_live_abc123... # auto-activates Layer 1
274
- SECURENOW_FIREWALL_TCP=1 # opt-in Layer 2
275
- SECURENOW_FIREWALL_IPTABLES=1 # opt-in Layer 3 (Linux, needs root)
276
- SECURENOW_FIREWALL_CLOUD=cloudflare # opt-in Layer 4
277
- ```
278
-
279
- ### Firewall-Only Mode (No Tracing Overhead)
280
-
281
- ```bash
282
- node -r securenow/firewall-only app.js
283
- ```
284
-
285
- Loads only dotenv + firewall. No OpenTelemetry, no tracing, no external packages needed.
286
-
287
- ### Programmatic Firewall API
288
-
289
- ```javascript
290
- const firewall = require('securenow/firewall');
291
-
292
- await firewall.init({
293
- apiKey: process.env.SECURENOW_API_KEY,
294
- apiUrl: 'https://api.securenow.ai',
295
- syncInterval: 300, // full sync every 5 min
296
- versionCheckInterval: 10, // lightweight version check every 10s
297
- failMode: 'open', // 'open' or 'closed'
298
- statusCode: 403,
299
- log: true,
300
- tcp: false,
301
- iptables: false,
302
- cloud: null, // 'cloudflare' | 'aws' | 'gcp'
303
- });
304
-
305
- const stats = firewall.getStats();
306
- const matcher = firewall.getMatcher(); // (ip) => boolean
307
- const allowMatcher = firewall.getAllowlistMatcher();
308
-
309
- await firewall.shutdown();
310
- ```
311
-
312
- ### Cloud WAF Providers
313
-
314
- **Cloudflare:**
315
- ```bash
316
- SECURENOW_FIREWALL_CLOUD=cloudflare
317
- CLOUDFLARE_API_TOKEN=your-token
318
- CLOUDFLARE_ACCOUNT_ID=your-account-id
319
- ```
320
-
321
- **AWS WAF:**
322
- ```bash
323
- SECURENOW_FIREWALL_CLOUD=aws
324
- AWS_WAF_IP_SET_ID=your-ip-set-id
325
- # + standard AWS credentials (env, profile, or IAM role)
326
- ```
327
- Requires peer dep: `npm install @aws-sdk/client-wafv2`
328
-
329
- **GCP Cloud Armor:**
330
- ```bash
331
- SECURENOW_FIREWALL_CLOUD=gcp
332
- GCP_PROJECT_ID=your-project
333
- GCP_SECURITY_POLICY=your-policy-name
334
- ```
335
- Requires peer dep: `npm install @google-cloud/compute`
336
-
337
- **Dry-run (log only, no actual WAF changes):**
338
- ```bash
339
- SECURENOW_FIREWALL_CLOUD_DRY_RUN=1
340
- ```
341
-
342
- ---
343
-
344
- ## Logging
345
-
346
- Logging is enabled by default (`SECURENOW_LOGGING_ENABLED=1`). Logs are exported to your OTLP collector alongside traces.
347
-
348
- ### Get a Logger
349
-
350
- ```javascript
351
- const { getLogger } = require('securenow/tracing');
352
-
353
- const logger = getLogger('my-module', '1.0.0');
354
- if (logger) {
355
- logger.emit({ body: 'User login succeeded', severityText: 'INFO', attributes: { userId: '123' } });
356
- }
357
- ```
358
-
359
- ### Console Instrumentation
360
-
361
- When tracing is active, `console.log/warn/error` are automatically patched to emit OTLP log records correlated with the active trace span. To access the original console:
362
-
363
- ```javascript
364
- const { originalConsole, restoreConsole } = require('securenow/console-instrumentation');
365
- originalConsole.log('This bypasses OTLP');
366
- restoreConsole(); // undo the patch
367
- ```
368
-
369
- ---
370
-
371
- ## IP Resolution Utilities
372
-
373
- ```javascript
374
- const { resolveClientIp, resolveSocketIp, isFromTrustedProxy } = require('securenow/resolve-ip');
375
-
376
- // From an HTTP request (respects X-Forwarded-For from trusted proxies)
377
- const clientIp = resolveClientIp(req);
378
-
379
- // Direct socket IP
380
- const socketIp = resolveSocketIp(req);
381
-
382
- // Check if request comes from a trusted proxy
383
- const trusted = isFromTrustedProxy(req);
384
- ```
385
-
386
- ### CIDR Matching
387
-
388
- ```javascript
389
- const { createMatcher, ipToInt, parseCidr, matchesCidr } = require('securenow/cidr');
390
-
391
- const isBlocked = createMatcher(['10.0.0.0/8', '192.168.1.0/24']);
392
- isBlocked('10.0.0.5'); // true
393
- isBlocked('8.8.8.8'); // false
394
- ```
395
-
396
- ---
397
-
398
- ## Sensitive Data Redaction
399
-
400
- Available from multiple entry points (`securenow/nextjs-middleware`, `securenow/nextjs-wrapper`, `securenow/nextjs-auto-capture`):
401
-
402
- ```javascript
403
- const { redactSensitiveData, DEFAULT_SENSITIVE_FIELDS } = require('securenow/nextjs-middleware');
404
-
405
- const safe = redactSensitiveData({ username: 'alice', password: 's3cret', token: 'abc' });
406
- // { username: 'alice', password: '[REDACTED]', token: '[REDACTED]' }
407
- ```
408
-
409
- **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`.
410
-
411
- Add custom fields via `SECURENOW_SENSITIVE_FIELDS=field1,field2`.
412
-
413
- ---
414
-
415
- ## Environment Variables — Complete Reference
416
-
417
- ### Required
418
-
419
- | Variable | Description | Default |
420
- |----------|-------------|---------|
421
- | `SECURENOW_APPID` | Service name / app identifier | *(auto-generated with UUID)* |
422
- | `SECURENOW_INSTANCE` | OTLP collector base URL | `https://freetrial.securenow.ai:4318` |
423
-
424
- ### Service Naming
425
-
426
- | Variable | Description | Default |
427
- |----------|-------------|---------|
428
- | `OTEL_SERVICE_NAME` | OpenTelemetry standard; overrides `SECURENOW_APPID` | — |
429
- | `SECURENOW_NO_UUID` | `1` to use exact app ID without UUID suffix | `0` |
430
- | `SECURENOW_STRICT` | `1` to exit if APPID missing in PM2 cluster | `0` |
431
-
432
- ### OTLP Connection
433
-
434
- | Variable | Description | Default |
435
- |----------|-------------|---------|
436
- | `OTEL_EXPORTER_OTLP_ENDPOINT` | Standard OTel endpoint; overrides `SECURENOW_INSTANCE` | — |
437
- | `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Override traces endpoint specifically | `{instance}/v1/traces` |
438
- | `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Override logs endpoint specifically | `{instance}/v1/logs` |
439
- | `OTEL_EXPORTER_OTLP_HEADERS` | Comma-separated `key=value` headers for OTLP requests | — |
440
-
441
- ### Behavior
442
-
443
- | Variable | Description | Default |
444
- |----------|-------------|---------|
445
- | `SECURENOW_LOGGING_ENABLED` | Enable OTLP log export | `1` |
446
- | `SECURENOW_CAPTURE_BODY` | Capture HTTP request bodies | `0` |
447
- | `SECURENOW_MAX_BODY_SIZE` | Max body size in bytes | `10240` |
448
- | `SECURENOW_CAPTURE_MULTIPART` | Capture multipart/form-data (streaming, metadata only) | `0` |
449
- | `SECURENOW_SENSITIVE_FIELDS` | Comma-separated extra fields to redact | — |
450
- | `SECURENOW_DISABLE_INSTRUMENTATIONS` | Comma-separated packages to skip (e.g. `fs,dns`) | — |
451
- | `SECURENOW_TEST_SPAN` | `1` to emit a test span on startup | `0` |
452
- | `SECURENOW_HIDE_BANNER` | `1` to suppress free-trial upgrade banner | `0` |
453
- | `OTEL_LOG_LEVEL` | SDK log level: `none`, `error`, `warn`, `info`, `debug` | `none` |
454
- | `NODE_ENV` | Sent as `deployment.environment` attribute | `production` |
455
-
456
- ### Firewall
457
-
458
- | Variable | Description | Default |
459
- |----------|-------------|---------|
460
- | `SECURENOW_API_KEY` | API key (`snk_live_...`); activates firewall when set | — |
461
- | `SECURENOW_API_URL` | SecureNow API base URL | `https://api.securenow.ai` |
462
- | `SECURENOW_FIREWALL_ENABLED` | Master kill-switch (`0` to disable) | `1` |
463
- | `SECURENOW_FIREWALL_VERSION_INTERVAL` | Seconds between lightweight version checks | `10` |
464
- | `SECURENOW_FIREWALL_SYNC_INTERVAL` | Full blocklist refresh interval in seconds | `300` |
465
- | `SECURENOW_FIREWALL_FAIL_MODE` | `open` (allow all when unavailable) or `closed` | `open` |
466
- | `SECURENOW_FIREWALL_STATUS_CODE` | HTTP status for blocked requests | `403` |
467
- | `SECURENOW_FIREWALL_LOG` | Log blocked requests | `1` |
468
- | `SECURENOW_FIREWALL_TCP` | Enable Layer 2 TCP blocking | `0` |
469
- | `SECURENOW_FIREWALL_IPTABLES` | Enable Layer 3 iptables/nftables | `0` |
470
- | `SECURENOW_FIREWALL_CLOUD` | Cloud WAF: `cloudflare`, `aws`, or `gcp` | — |
471
- | `SECURENOW_FIREWALL_CLOUD_DRY_RUN` | `1` to log cloud pushes without applying | `0` |
472
- | `SECURENOW_TRUSTED_PROXIES` | Comma-separated trusted proxy IPs | — |
473
-
474
- **Resilience:** The firewall SDK includes a circuit breaker (opens after 5 consecutive errors, 2-min cooldown), in-flight request guards (prevents overlapping requests), 429 Retry-After support, and exponential backoff on both version checks and initial sync retries.
475
-
476
- ### Cloud WAF Provider Variables
477
-
478
- | Provider | Variables |
479
- |----------|-----------|
480
- | Cloudflare | `CLOUDFLARE_API_TOKEN`, `CLOUDFLARE_ACCOUNT_ID` |
481
- | AWS WAF | `AWS_WAF_IP_SET_ID`, `AWS_WAF_IP_SET_NAME`, `AWS_WAF_SCOPE` |
482
- | GCP | `GCP_PROJECT_ID`, `GCP_SECURITY_POLICY` |
483
-
484
- ### Priority Order
485
-
486
- **Service name:** `OTEL_SERVICE_NAME` > `SECURENOW_APPID` > auto-generated
487
-
488
- **Endpoint:** `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` > `OTEL_EXPORTER_OTLP_ENDPOINT` > `SECURENOW_INSTANCE` > `https://freetrial.securenow.ai:4318`
489
-
490
- ---
491
-
492
- ## Recipes for Agentic AI
493
-
494
- ### Add Observability to an Existing Express App
495
-
496
- ```bash
497
- npm install securenow
498
- ```
499
-
500
- Create `.env`:
501
- ```
502
- SECURENOW_APPID=my-express-api
503
- SECURENOW_INSTANCE=https://your-collector:4318
504
- SECURENOW_LOGGING_ENABLED=1
505
- SECURENOW_CAPTURE_BODY=1
506
- ```
507
-
508
- Update `package.json`:
509
- ```json
510
- { "scripts": { "start": "node -r securenow/register src/index.js" } }
511
- ```
512
-
513
- No code changes to the application needed.
514
-
515
- ### Add Observability + Firewall to a Next.js App
516
-
517
- ```bash
518
- npm install securenow
519
- npx securenow init --key snk_live_abc123...
520
- ```
521
-
522
- The `init` command creates `instrumentation.ts` and suggests `next.config` changes. Then set env vars in `.env.local`:
523
-
524
- ```
525
- SECURENOW_APPID=my-nextjs-app
526
- SECURENOW_INSTANCE=https://your-collector:4318
527
- SECURENOW_API_KEY=snk_live_abc123...
528
- SECURENOW_CAPTURE_BODY=1
529
- ```
530
-
531
- ### Enable Firewall With Zero Tracing Overhead
532
-
533
- For apps that only need IP blocking:
534
-
535
- ```bash
536
- node -r securenow/firewall-only app.js
537
- ```
538
-
539
- Set `SECURENOW_API_KEY` in the environment. No other configuration needed.
540
-
541
- ### Production Hardened Configuration
542
-
543
- ```bash
544
- SECURENOW_APPID=prod-api
545
- SECURENOW_INSTANCE=https://collector.prod.internal:4318
546
- SECURENOW_NO_UUID=1
547
- SECURENOW_STRICT=1
548
- SECURENOW_LOGGING_ENABLED=1
549
- SECURENOW_CAPTURE_BODY=0
550
- SECURENOW_API_KEY=snk_live_abc123...
551
- SECURENOW_FIREWALL_TCP=1
552
- SECURENOW_FIREWALL_SYNC_INTERVAL=30
553
- SECURENOW_FIREWALL_FAIL_MODE=open
554
- OTEL_LOG_LEVEL=error
555
- NODE_ENV=production
556
- ```
557
-
558
- ### Instrument a Docker Container
559
-
560
- ```dockerfile
561
- FROM node:20-slim
562
- WORKDIR /app
563
- COPY package*.json ./
564
- RUN npm ci --omit=dev
565
- COPY . .
566
-
567
- ENV SECURENOW_APPID=my-service
568
- ENV SECURENOW_INSTANCE=http://otel-collector:4318
569
- ENV SECURENOW_NO_UUID=1
570
- ENV SECURENOW_API_KEY=snk_live_abc123...
571
-
572
- CMD ["node", "-r", "securenow/register", "src/index.js"]
573
- ```
574
-
575
- ### Kubernetes with Separate Trace/Log Collectors
576
-
577
- ```bash
578
- SECURENOW_APPID=k8s-service
579
- OTEL_EXPORTER_OTLP_TRACES_ENDPOINT=http://tempo:4318/v1/traces
580
- OTEL_EXPORTER_OTLP_LOGS_ENDPOINT=http://loki:4318/v1/logs
581
- SECURENOW_LOGGING_ENABLED=1
582
- SECURENOW_NO_UUID=1
583
- ```
584
-
585
- ---
586
-
587
- ## Verification
588
-
589
- On startup, securenow logs its configuration:
590
-
591
- ```
592
- [securenow] pid=12345 SECURENOW_APPID="my-app" → service.name=my-app
593
- [securenow] OTel SDK started → https://collector:4318/v1/traces
594
- [securenow] Logging: ENABLED → https://collector:4318/v1/logs
595
- [securenow] Request body capture: ENABLED (max: 10240 bytes)
596
- [securenow] Firewall: ENABLED
597
- [securenow] Firewall: synced 142 blocked IPs
598
- ```
599
-
600
- Use `OTEL_LOG_LEVEL=debug` and `SECURENOW_TEST_SPAN=1` to troubleshoot connectivity issues.