securenow 6.0.2 → 6.1.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 (87) hide show
  1. package/CONSUMING-APPS-GUIDE.md +455 -0
  2. package/NPM_README.md +2029 -0
  3. package/README.md +297 -40
  4. package/SKILL-API.md +634 -0
  5. package/SKILL-CLI.md +454 -0
  6. package/cidr.js +83 -0
  7. package/cli/apps.js +585 -0
  8. package/cli/auth.js +280 -0
  9. package/cli/client.js +115 -0
  10. package/cli/config.js +173 -0
  11. package/cli/diagnostics.js +387 -0
  12. package/cli/firewall.js +100 -0
  13. package/cli/fp.js +638 -0
  14. package/cli/init.js +201 -0
  15. package/cli/monitor.js +440 -0
  16. package/cli/run.js +148 -0
  17. package/cli/security.js +980 -0
  18. package/cli/ui.js +386 -0
  19. package/cli/utils.js +127 -0
  20. package/cli.js +466 -455
  21. package/console-instrumentation.js +147 -136
  22. package/docs/ALL-FRAMEWORKS-QUICKSTART.md +1377 -455
  23. package/docs/API-KEYS-GUIDE.md +233 -0
  24. package/docs/ARCHITECTURE.md +3 -3
  25. package/docs/AUTO-BODY-CAPTURE.md +1 -1
  26. package/docs/AUTO-SETUP-SUMMARY.md +331 -0
  27. package/docs/AUTO-SETUP.md +4 -4
  28. package/docs/AUTOMATIC-IP-CAPTURE.md +5 -5
  29. package/docs/BODY-CAPTURE-FIX.md +261 -0
  30. package/docs/BODY-CAPTURE-QUICKSTART.md +2 -2
  31. package/docs/CHANGELOG-NEXTJS.md +1 -35
  32. package/docs/COMPLETION-REPORT.md +408 -0
  33. package/docs/CUSTOMER-GUIDE.md +16 -16
  34. package/docs/EASIEST-SETUP.md +5 -5
  35. package/docs/ENVIRONMENT-VARIABLES.md +880 -652
  36. package/docs/EXPRESS-BODY-CAPTURE.md +13 -12
  37. package/docs/EXPRESS-SETUP-GUIDE.md +719 -720
  38. package/docs/FINAL-SOLUTION.md +335 -0
  39. package/docs/FIREWALL-GUIDE.md +426 -0
  40. package/docs/IMPLEMENTATION-SUMMARY.md +410 -0
  41. package/docs/INDEX.md +22 -4
  42. package/docs/LOGGING-GUIDE.md +701 -708
  43. package/docs/LOGGING-QUICKSTART.md +234 -255
  44. package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +323 -0
  45. package/docs/NEXTJS-BODY-CAPTURE.md +2 -2
  46. package/docs/NEXTJS-GUIDE.md +14 -14
  47. package/docs/NEXTJS-QUICKSTART.md +1 -1
  48. package/docs/NEXTJS-SETUP-COMPLETE.md +795 -0
  49. package/docs/NEXTJS-WRAPPER-APPROACH.md +1 -1
  50. package/docs/NUXT-GUIDE.md +166 -0
  51. package/docs/QUICKSTART-BODY-CAPTURE.md +2 -2
  52. package/docs/REDACTION-EXAMPLES.md +1 -1
  53. package/docs/REQUEST-BODY-CAPTURE.md +19 -10
  54. package/docs/SOLUTION-SUMMARY.md +312 -0
  55. package/docs/VERCEL-OTEL-MIGRATION.md +3 -3
  56. package/examples/README.md +6 -6
  57. package/examples/instrumentation-with-auto-capture.ts +1 -1
  58. package/examples/nextjs-env-example.txt +2 -2
  59. package/examples/nextjs-instrumentation.js +1 -1
  60. package/examples/nextjs-instrumentation.ts +1 -1
  61. package/examples/nextjs-with-logging-example.md +6 -6
  62. package/examples/nextjs-with-options.ts +1 -1
  63. package/examples/test-nextjs-setup.js +1 -1
  64. package/firewall-cloud.js +212 -0
  65. package/firewall-iptables.js +139 -0
  66. package/firewall-only.js +38 -0
  67. package/firewall-tcp.js +74 -0
  68. package/firewall.js +720 -0
  69. package/free-trial-banner.js +174 -0
  70. package/nextjs-auto-capture.js +199 -207
  71. package/nextjs-middleware.js +186 -181
  72. package/nextjs-webpack-config.js +88 -53
  73. package/nextjs-wrapper.js +158 -158
  74. package/nextjs.d.ts +1 -1
  75. package/nextjs.js +639 -647
  76. package/nuxt-server-plugin.mjs +423 -0
  77. package/nuxt.d.ts +60 -0
  78. package/nuxt.mjs +75 -0
  79. package/package.json +186 -164
  80. package/postinstall.js +6 -6
  81. package/register.d.ts +1 -1
  82. package/register.js +39 -4
  83. package/resolve-ip.js +77 -0
  84. package/tracing.d.ts +2 -1
  85. package/tracing.js +295 -34
  86. package/web-vite.mjs +239 -156
  87. package/LICENSE +0 -15
@@ -1,455 +1,1377 @@
1
- # Quick Start Guide - All Frameworks
2
-
3
- Fast setup guide for SecureNow with any Node.js framework in under 5 minutes.
4
-
5
- ---
6
-
7
- ## Universal Setup (Works with Any Framework)
8
-
9
- ### Step 1: Install
10
-
11
- ```bash
12
- npm install securenow
13
- ```
14
-
15
- ### Step 2: Set Environment Variables
16
-
17
- ```bash
18
- export SECURENOW_APPID=my-app
19
- export SECURENOW_INSTANCE=http://localhost:4318
20
- export SECURENOW_LOGGING_ENABLED=1
21
- ```
22
-
23
- ### Step 3: Initialize
24
-
25
- **Option A: Using NODE_OPTIONS (No code changes)**
26
-
27
- ```bash
28
- NODE_OPTIONS="-r securenow/register -r securenow/console-instrumentation" node app.js
29
- ```
30
-
31
- **Option B: Add to your code**
32
-
33
- ```javascript
34
- // At the very top of your main file
35
- require('securenow/register');
36
- require('securenow/console-instrumentation');
37
-
38
- // Rest of your application
39
- ```
40
-
41
- **Done!** Your app is now sending traces and logs.
42
-
43
- ---
44
-
45
- ## Framework-Specific Quick Starts
46
-
47
- ### Express.js
48
-
49
- ```javascript
50
- // app.js
51
- require('securenow/register');
52
- require('securenow/console-instrumentation');
53
-
54
- const express = require('express');
55
- const app = express();
56
-
57
- app.get('/', (req, res) => {
58
- console.log('Request received');
59
- res.send('Hello World');
60
- });
61
-
62
- app.listen(3000);
63
- ```
64
-
65
- **Run:**
66
- ```bash
67
- SECURENOW_APPID=express-app \
68
- SECURENOW_INSTANCE=http://localhost:4318 \
69
- node app.js
70
- ```
71
-
72
- [Full Express Guide →](./EXPRESS-SETUP-GUIDE.md)
73
-
74
- ---
75
-
76
- ### Next.js (App Router)
77
-
78
- **1. Create `instrumentation.ts` in project root:**
79
-
80
- ```typescript
81
- export async function register() {
82
- if (process.env.NEXT_RUNTIME === 'nodejs') {
83
- process.env.SECURENOW_LOGGING_ENABLED = '1';
84
- await import('securenow/register');
85
- await import('securenow/console-instrumentation');
86
- }
87
- }
88
- ```
89
-
90
- **2. Enable in `next.config.js`:**
91
-
92
- ```javascript
93
- module.exports = {
94
- experimental: {
95
- instrumentationHook: true,
96
- },
97
- };
98
- ```
99
-
100
- **3. Create `.env.local`:**
101
-
102
- ```env
103
- SECURENOW_APPID=nextjs-app
104
- SECURENOW_INSTANCE=http://localhost:4318
105
- ```
106
-
107
- **4. Run:**
108
-
109
- ```bash
110
- npm run dev
111
- ```
112
-
113
- [Full Next.js Guide →](./NEXTJS-SETUP-COMPLETE.md)
114
-
115
- ---
116
-
117
- ### Fastify
118
-
119
- ```javascript
120
- // server.js
121
- require('securenow/register');
122
- require('securenow/console-instrumentation');
123
-
124
- const fastify = require('fastify')();
125
-
126
- fastify.get('/', async () => {
127
- console.log('Route called');
128
- return { hello: 'world' };
129
- });
130
-
131
- fastify.listen({ port: 3000 });
132
- ```
133
-
134
- **Run:**
135
- ```bash
136
- SECURENOW_APPID=fastify-app node server.js
137
- ```
138
-
139
- ---
140
-
141
- ### NestJS
142
-
143
- ```typescript
144
- // src/main.ts
145
- require('securenow/register');
146
- require('securenow/console-instrumentation');
147
-
148
- import { NestFactory } from '@nestjs/core';
149
- import { AppModule } from './app.module';
150
-
151
- async function bootstrap() {
152
- const app = await NestFactory.create(AppModule);
153
- await app.listen(3000);
154
- }
155
-
156
- bootstrap();
157
- ```
158
-
159
- **Run:**
160
- ```bash
161
- npm run start
162
- ```
163
-
164
- ---
165
-
166
- ### Koa
167
-
168
- ```javascript
169
- // app.js
170
- require('securenow/register');
171
- require('securenow/console-instrumentation');
172
-
173
- const Koa = require('koa');
174
- const app = new Koa();
175
-
176
- app.use(async ctx => {
177
- console.log('Request received');
178
- ctx.body = 'Hello World';
179
- });
180
-
181
- app.listen(3000);
182
- ```
183
-
184
- ---
185
-
186
- ### Hapi
187
-
188
- ```javascript
189
- // server.js
190
- require('securenow/register');
191
- require('securenow/console-instrumentation');
192
-
193
- const Hapi = require('@hapi/hapi');
194
-
195
- const init = async () => {
196
- const server = Hapi.server({ port: 3000 });
197
-
198
- server.route({
199
- method: 'GET',
200
- path: '/',
201
- handler: () => {
202
- console.log('Route called');
203
- return 'Hello World';
204
- }
205
- });
206
-
207
- await server.start();
208
- };
209
-
210
- init();
211
- ```
212
-
213
- ---
214
-
215
- ## Environment Variables
216
-
217
- ### Minimal Setup
218
-
219
- ```bash
220
- SECURENOW_APPID=my-app
221
- SECURENOW_INSTANCE=http://localhost:4318
222
- ```
223
-
224
- ### Recommended Setup
225
-
226
- ```bash
227
- SECURENOW_APPID=my-app
228
- SECURENOW_INSTANCE=http://localhost:4318
229
- SECURENOW_LOGGING_ENABLED=1
230
- SECURENOW_CAPTURE_BODY=1
231
- NODE_ENV=development
232
- ```
233
-
234
- ### Production Setup
235
-
236
- ```bash
237
- SECURENOW_APPID=my-app-prod
238
- SECURENOW_INSTANCE=http://collector.prod:4318
239
- OTEL_EXPORTER_OTLP_HEADERS=x-api-key=your-key
240
- SECURENOW_LOGGING_ENABLED=1
241
- SECURENOW_NO_UUID=1
242
- SECURENOW_CAPTURE_BODY=0
243
- NODE_ENV=production
244
- ```
245
-
246
- [Complete Environment Variables Reference →](./ENVIRONMENT-VARIABLES.md)
247
-
248
- ---
249
-
250
- ## Logging Examples
251
-
252
- ### Automatic Console Logging
253
-
254
- ```javascript
255
- // All console methods are automatically captured
256
- console.log('Application started');
257
- console.info('User action', { userId: 123 });
258
- console.warn('Warning message');
259
- console.error('Error occurred', { error: 'details' });
260
- ```
261
-
262
- ### Direct Logger API
263
-
264
- ```javascript
265
- const { getLogger } = require('securenow/tracing');
266
- const logger = getLogger('my-module', '1.0.0');
267
-
268
- logger.emit({
269
- severityNumber: 9,
270
- severityText: 'INFO',
271
- body: 'Custom log message',
272
- attributes: {
273
- userId: 123,
274
- action: 'login',
275
- },
276
- });
277
- ```
278
-
279
- [Complete Logging Guide →](./LOGGING-GUIDE.md)
280
-
281
- ---
282
-
283
- ## Request Body Capture
284
-
285
- Enable request body capture for debugging:
286
-
287
- ```bash
288
- export SECURENOW_CAPTURE_BODY=1
289
- export SECURENOW_MAX_BODY_SIZE=10240 # 10KB
290
- ```
291
-
292
- **Automatically redacted:** passwords, tokens, API keys, card numbers, etc.
293
-
294
- ---
295
-
296
- ## PM2 Setup
297
-
298
- ```javascript
299
- // ecosystem.config.js
300
- module.exports = {
301
- apps: [{
302
- name: 'my-app',
303
- script: './app.js',
304
- instances: 4,
305
- exec_mode: 'cluster',
306
- node_args: '-r securenow/register -r securenow/console-instrumentation',
307
- env: {
308
- SECURENOW_APPID: 'my-app',
309
- SECURENOW_INSTANCE: 'http://localhost:4318',
310
- SECURENOW_LOGGING_ENABLED: '1',
311
- SECURENOW_NO_UUID: '1',
312
- }
313
- }]
314
- };
315
- ```
316
-
317
- ```bash
318
- pm2 start ecosystem.config.js
319
- ```
320
-
321
- ---
322
-
323
- ## Docker Setup
324
-
325
- ```dockerfile
326
- FROM node:20-alpine
327
-
328
- WORKDIR /app
329
-
330
- COPY package*.json ./
331
- RUN npm install
332
-
333
- COPY . .
334
-
335
- ENV SECURENOW_APPID=my-app
336
- ENV SECURENOW_INSTANCE=http://collector:4318
337
- ENV SECURENOW_LOGGING_ENABLED=1
338
-
339
- EXPOSE 3000
340
- CMD ["node", "app.js"]
341
- ```
342
-
343
- ---
344
-
345
- ## Verification
346
-
347
- After starting your app, you should see:
348
-
349
- ```
350
- [securenow] OTel SDK started → http://localhost:4318/v1/traces
351
- [securenow] 📋 Logging: ENABLED → http://localhost:4318/v1/logs
352
- [securenow] Console instrumentation installed
353
- ```
354
-
355
- Check your observability backend - traces and logs should appear within seconds.
356
-
357
- ---
358
-
359
- ## Troubleshooting
360
-
361
- ### Traces Not Appearing
362
-
363
- 1. Check environment variables:
364
- ```bash
365
- echo $SECURENOW_APPID
366
- echo $SECURENOW_INSTANCE
367
- ```
368
-
369
- 2. Enable debug logging:
370
- ```bash
371
- export OTEL_LOG_LEVEL=debug
372
- node app.js
373
- ```
374
-
375
- 3. Verify collector is running:
376
- ```bash
377
- curl http://localhost:4318/v1/traces
378
- ```
379
-
380
- ### Logs Not Appearing
381
-
382
- 1. Check logging is enabled:
383
- ```bash
384
- echo $SECURENOW_LOGGING_ENABLED # Should be: 1
385
- ```
386
-
387
- 2. Verify console instrumentation loaded:
388
- ```
389
- [securenow] Console instrumentation installed
390
- ```
391
-
392
- 3. Check initialization order:
393
- ```javascript
394
- // ✅ Correct
395
- require('securenow/register');
396
- require('securenow/console-instrumentation');
397
- const express = require('express');
398
-
399
- // Wrong
400
- const express = require('express');
401
- require('securenow/register');
402
- ```
403
-
404
- ---
405
-
406
- ## Complete Documentation
407
-
408
- - **[NPM README](../NPM_README.md)** - Full npm package documentation
409
- - **[Express Guide](./EXPRESS-SETUP-GUIDE.md)** - Complete Express.js setup
410
- - **[Next.js Guide](./NEXTJS-SETUP-COMPLETE.md)** - Complete Next.js setup
411
- - **[Logging Guide](./LOGGING-GUIDE.md)** - Complete logging reference
412
- - **[Environment Variables](./ENVIRONMENT-VARIABLES.md)** - All variables explained
413
-
414
- ---
415
-
416
- ## What Gets Instrumented Automatically
417
-
418
- - HTTP/HTTPS (incoming and outgoing)
419
- - Express.js, Fastify, Koa, Hapi, Next.js
420
- - PostgreSQL, MySQL, MongoDB, Redis
421
- - GraphQL, gRPC
422
- - axios, fetch, node-fetch, got
423
- - And 50+ more libraries
424
-
425
- **No code changes needed!**
426
-
427
- ---
428
-
429
- ## Performance
430
-
431
- - **< 1% overhead:** Minimal CPU and memory impact
432
- - **Async processing:** No blocking of requests
433
- - **Batch export:** Efficient data transmission
434
- - **Production-ready:** Battle-tested in high-traffic applications
435
-
436
- ---
437
-
438
- ## Security
439
-
440
- - **Automatic redaction** of sensitive fields
441
- - **Configurable** field patterns
442
- - **No local storage** - data goes directly to your backend
443
- - **Open source** - audit the code yourself
444
-
445
- ---
446
-
447
- ## Support
448
-
449
- - **Documentation:** [GitHub Docs](https://github.com/your-repo/securenow-npm/tree/main/docs)
450
- - **Issues:** [GitHub Issues](https://github.com/your-repo/securenow-npm/issues)
451
- - **Examples:** [GitHub Examples](https://github.com/your-repo/securenow-npm/tree/main/examples)
452
-
453
- ---
454
-
455
- **Get your app observable in under 5 minutes!** 🚀
1
+ # SecureNow Complete Guide for Every Node.js Framework
2
+
3
+ Protect any Node.js app in minutes. This guide covers **installation, CLI commands, the forensics chat, and IP blocking** for all 11 supported frameworks.
4
+
5
+ ---
6
+
7
+ ## Table of Contents
8
+
9
+ 1. [Prerequisites](#prerequisites)
10
+ 2. [Install & Create Your App](#step-1--install--create-your-app)
11
+ 3. [Set Environment Variables](#step-2--set-environment-variables)
12
+ 4. [Plug SecureNow into Your Framework](#step-3--plug-securenow-into-your-framework)
13
+ - [Express.js](#expressjs)
14
+ - [Fastify](#fastify)
15
+ - [Koa](#koa)
16
+ - [NestJS](#nestjs)
17
+ - [Hapi](#hapi)
18
+ - [h3 (UnJS / Nitro)](#h3-unjs--nitro)
19
+ - [Polka](#polka)
20
+ - [Micro / Raw HTTP](#micro--raw-http)
21
+ - [Hono](#hono)
22
+ - [Feathers](#feathers)
23
+ - [Next.js](#nextjs)
24
+ 5. [Verify It Works](#step-4--verify-it-works)
25
+ 6. [CLI Command Reference](#step-5--cli-command-reference)
26
+ 7. [Forensics Chat — Ask Questions in Plain English](#step-6--forensics-chat--ask-questions-in-plain-english)
27
+ 8. [Block & Manage IPs + Firewall](#step-7--block--manage-ips)
28
+ 9. [Monitor, Detect & Respond](#step-8--monitor-detect--respond)
29
+ 10. [PM2 / Docker Deployment](#deployment)
30
+ 11. [Compatibility Matrix](#compatibility-matrix)
31
+ 12. [Troubleshooting](#troubleshooting)
32
+
33
+ ---
34
+
35
+ ## Prerequisites
36
+
37
+ | Requirement | Details |
38
+ |-------------|---------|
39
+ | **Node.js** | v16 or later |
40
+ | **npm** | v7 or later |
41
+ | **Account** | Free trial at [app.securenow.ai](https://app.securenow.ai) (no credit card) |
42
+
43
+ ---
44
+
45
+ ## Step 1 — Install & Create Your App
46
+
47
+ ### 1a. Install the package
48
+
49
+ ```bash
50
+ npm install securenow
51
+ ```
52
+
53
+ ### 1b. Authenticate the CLI
54
+
55
+ ```bash
56
+ npx securenow login
57
+ ```
58
+
59
+ This opens your browser. Log in with your SecureNow account and the CLI receives a session token automatically.
60
+
61
+ **Alternative — token-based login (CI / headless servers):**
62
+
63
+ ```bash
64
+ npx securenow login --token <YOUR_TOKEN>
65
+ ```
66
+
67
+ Get your CLI token from [app.securenow.ai/dashboard/settings](https://app.securenow.ai/dashboard/settings).
68
+
69
+ ### 1c. Create an application
70
+
71
+ ```bash
72
+ npx securenow apps create my-app
73
+ ```
74
+
75
+ The CLI returns your **app key** and **instance URL**. Copy them — you need both in the next step.
76
+
77
+ ```
78
+ Name my-app
79
+ Key my-app
80
+ Instance Free Trial (https://freetrial.securenow.ai:4318)
81
+
82
+ Add to your .env.local:
83
+ SECURENOW_APPID=my-app
84
+ SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
85
+ ```
86
+
87
+ ### 1d. Set it as the default app (optional)
88
+
89
+ ```bash
90
+ npx securenow config set defaultApp my-app
91
+ ```
92
+
93
+ This lets you run CLI commands like `securenow traces` without passing `--app` every time.
94
+
95
+ ---
96
+
97
+ ## Step 2 — Set Environment Variables
98
+
99
+ Create a `.env` file in your project root:
100
+
101
+ ```env
102
+ SECURENOW_APPID=my-app
103
+ SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
104
+ SECURENOW_LOGGING_ENABLED=1
105
+ SECURENOW_NO_UUID=1
106
+ ```
107
+
108
+ ### All Environment Variables
109
+
110
+ | Variable | Purpose | Default |
111
+ |----------|---------|---------|
112
+ | `SECURENOW_APPID` | Your app key (from `securenow apps create`) | **Required** |
113
+ | `SECURENOW_INSTANCE` | OTLP collector endpoint | `https://freetrial.securenow.ai:4318` |
114
+ | `SECURENOW_LOGGING_ENABLED` | Auto-forward all `console.*` calls as OTLP logs | `0` |
115
+ | `SECURENOW_NO_UUID` | Keep `service.name` equal to your app key (no UUID suffix) | `0` |
116
+ | `SECURENOW_CAPTURE_BODY` | Capture request/response bodies in traces | `0` |
117
+ | `SECURENOW_MAX_BODY_SIZE` | Max captured body size in bytes | `10240` |
118
+ | `SECURENOW_SENSITIVE_FIELDS` | Extra field names to auto-redact (comma-separated) | — |
119
+ | `SECURENOW_TRUSTED_PROXIES` | Comma-separated proxy IPs for X-Forwarded-For | — |
120
+ | `SECURENOW_DISABLE_INSTRUMENTATIONS` | OTel instrumentation packages to skip (comma-separated) | — |
121
+ | `SECURENOW_HIDE_BANNER` | Hide the free-trial testing banner | `0` |
122
+ | `SECURENOW_STRICT` | Exit if `APPID` is missing in PM2 cluster mode | `0` |
123
+ | `OTEL_LOG_LEVEL` | OTel diagnostic level (`debug`, `info`, `warn`, `error`, `none`) | `none` |
124
+
125
+ ### Production Example
126
+
127
+ ```env
128
+ SECURENOW_APPID=my-app-prod
129
+ SECURENOW_INSTANCE=https://collector.yourcompany.com:4318
130
+ SECURENOW_LOGGING_ENABLED=1
131
+ SECURENOW_NO_UUID=1
132
+ SECURENOW_CAPTURE_BODY=0
133
+ SECURENOW_TRUSTED_PROXIES=10.0.0.1,10.0.0.2
134
+ NODE_ENV=production
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Step 3 — Plug SecureNow into Your Framework
140
+
141
+ There are two ways to initialize SecureNow. Both work with every framework.
142
+
143
+ **Option A — Zero code changes (recommended)**
144
+
145
+ ```bash
146
+ node -r securenow/register app.js
147
+ ```
148
+
149
+ **Option B Add one line to your entry file**
150
+
151
+ ```javascript
152
+ require('securenow/register'); // Must be the very first line
153
+ ```
154
+
155
+ Pick **one** method. Both do the same thing. Below are complete, copy-paste examples for each framework.
156
+
157
+ ---
158
+
159
+ ### Express.js
160
+
161
+ ```bash
162
+ npm install securenow express
163
+ ```
164
+
165
+ ```javascript
166
+ // app.js
167
+ 'use strict';
168
+ require('securenow/register');
169
+ const express = require('express');
170
+
171
+ const app = express();
172
+ app.use(express.json());
173
+
174
+ app.get('/health', (req, res) => {
175
+ res.json({ status: 'ok' });
176
+ });
177
+
178
+ app.post('/tasks', (req, res) => {
179
+ const { title } = req.body;
180
+ if (!title) return res.status(400).json({ error: 'title is required' });
181
+ console.log('Created task:', title);
182
+ res.status(201).json({ id: '1', title });
183
+ });
184
+
185
+ app.listen(3000, () => {
186
+ console.log('Express app running on port 3000');
187
+ });
188
+ ```
189
+
190
+ ```bash
191
+ node app.js
192
+ ```
193
+
194
+ | Feature | Supported |
195
+ |---------|-----------|
196
+ | Traces | Yes |
197
+ | Logs | Yes |
198
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
199
+
200
+ ---
201
+
202
+ ### Fastify
203
+
204
+ ```bash
205
+ npm install securenow fastify
206
+ ```
207
+
208
+ ```javascript
209
+ // app.js
210
+ 'use strict';
211
+ require('securenow/register');
212
+ const Fastify = require('fastify');
213
+
214
+ const fastify = Fastify({ logger: true });
215
+
216
+ fastify.get('/health', async () => {
217
+ return { status: 'ok' };
218
+ });
219
+
220
+ fastify.post('/tasks', {
221
+ schema: {
222
+ body: { type: 'object', required: ['title'], properties: { title: { type: 'string' } } }
223
+ }
224
+ }, async (request) => {
225
+ const { title } = request.body;
226
+ console.log('Created task:', title);
227
+ return { id: '1', title };
228
+ });
229
+
230
+ fastify.listen({ port: 3000 }, (err) => {
231
+ if (err) { fastify.log.error(err); process.exit(1); }
232
+ console.log('Fastify app running on port 3000');
233
+ });
234
+ ```
235
+
236
+ ```bash
237
+ node app.js
238
+ ```
239
+
240
+ | Feature | Supported |
241
+ |---------|-----------|
242
+ | Traces | Yes |
243
+ | Logs | Yes |
244
+ | Body Capture | **No** — set `SECURENOW_CAPTURE_BODY=0` (stream conflict) |
245
+
246
+ ---
247
+
248
+ ### Koa
249
+
250
+ ```bash
251
+ npm install securenow koa @koa/router koa-bodyparser
252
+ ```
253
+
254
+ ```javascript
255
+ // app.js
256
+ 'use strict';
257
+ require('securenow/register');
258
+ const Koa = require('koa');
259
+ const Router = require('@koa/router');
260
+ const bodyParser = require('koa-bodyparser');
261
+
262
+ const app = new Koa();
263
+ const router = new Router();
264
+
265
+ router.get('/health', (ctx) => {
266
+ ctx.body = { status: 'ok' };
267
+ });
268
+
269
+ router.post('/tasks', (ctx) => {
270
+ const { title } = ctx.request.body;
271
+ if (!title) { ctx.status = 400; ctx.body = { error: 'title is required' }; return; }
272
+ console.log('Created task:', title);
273
+ ctx.status = 201;
274
+ ctx.body = { id: '1', title };
275
+ });
276
+
277
+ app.use(bodyParser());
278
+ app.use(router.routes());
279
+ app.use(router.allowedMethods());
280
+
281
+ app.listen(3000, () => {
282
+ console.log('Koa app running on port 3000');
283
+ });
284
+ ```
285
+
286
+ ```bash
287
+ node app.js
288
+ ```
289
+
290
+ | Feature | Supported |
291
+ |---------|-----------|
292
+ | Traces | Yes |
293
+ | Logs | Yes |
294
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
295
+
296
+ ---
297
+
298
+ ### NestJS
299
+
300
+ ```bash
301
+ npm install securenow
302
+ ```
303
+
304
+ NestJS uses TypeScript. Create an `instrument.js` file in your project root to load SecureNow before anything else:
305
+
306
+ ```javascript
307
+ // instrument.js
308
+ require('securenow/register');
309
+ ```
310
+
311
+ Your NestJS entry file stays unchanged:
312
+
313
+ ```typescript
314
+ // src/main.ts
315
+ import 'reflect-metadata';
316
+ import { NestFactory } from '@nestjs/core';
317
+ import { Module, Controller, Get, Post, Body } from '@nestjs/common';
318
+
319
+ @Controller()
320
+ class AppController {
321
+ @Get('health')
322
+ health() {
323
+ return { status: 'ok' };
324
+ }
325
+
326
+ @Post('tasks')
327
+ create(@Body() body: { title: string }) {
328
+ console.log('Created task:', body.title);
329
+ return { id: '1', title: body.title };
330
+ }
331
+ }
332
+
333
+ @Module({ controllers: [AppController] })
334
+ class AppModule {}
335
+
336
+ async function bootstrap() {
337
+ const app = await NestFactory.create(AppModule);
338
+ await app.listen(3000);
339
+ console.log('NestJS app running on port 3000');
340
+ }
341
+ bootstrap();
342
+ ```
343
+
344
+ **Development (ts-node):**
345
+
346
+ ```bash
347
+ node -r ./instrument.js -r ts-node/register src/main.ts
348
+ ```
349
+
350
+ **Production (compiled):**
351
+
352
+ ```bash
353
+ node -r ./instrument.js dist/main.js
354
+ ```
355
+
356
+ Add both to your `package.json`:
357
+
358
+ ```json
359
+ {
360
+ "scripts": {
361
+ "start:dev": "node -r ./instrument.js -r ts-node/register src/main.ts",
362
+ "start": "node -r ./instrument.js dist/main.js"
363
+ }
364
+ }
365
+ ```
366
+
367
+ | Feature | Supported |
368
+ |---------|-----------|
369
+ | Traces | Yes |
370
+ | Logs | Yes |
371
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
372
+
373
+ ---
374
+
375
+ ### Hapi
376
+
377
+ ```bash
378
+ npm install securenow @hapi/hapi
379
+ ```
380
+
381
+ ```javascript
382
+ // app.js
383
+ 'use strict';
384
+ require('securenow/register');
385
+ const Hapi = require('@hapi/hapi');
386
+
387
+ const init = async () => {
388
+ const server = Hapi.server({ port: 3000, host: '0.0.0.0' });
389
+
390
+ server.route({
391
+ method: 'GET', path: '/health',
392
+ handler: () => ({ status: 'ok' })
393
+ });
394
+
395
+ server.route({
396
+ method: 'POST', path: '/tasks',
397
+ options: { payload: { parse: true, allow: 'application/json' } },
398
+ handler: (request, h) => {
399
+ const { title } = request.payload || {};
400
+ if (!title) return h.response({ error: 'title is required' }).code(400);
401
+ console.log('Created task:', title);
402
+ return h.response({ id: '1', title }).code(201);
403
+ }
404
+ });
405
+
406
+ await server.start();
407
+ console.log('Hapi app running on port 3000');
408
+ };
409
+
410
+ init().catch((err) => { console.error(err); process.exit(1); });
411
+ ```
412
+
413
+ ```bash
414
+ node app.js
415
+ ```
416
+
417
+ | Feature | Supported |
418
+ |---------|-----------|
419
+ | Traces | Yes |
420
+ | Logs | Yes |
421
+ | Body Capture | **No** — set `SECURENOW_CAPTURE_BODY=0` (payload stream conflict) |
422
+
423
+ ---
424
+
425
+ ### h3 (UnJS / Nitro)
426
+
427
+ ```bash
428
+ npm install securenow h3
429
+ ```
430
+
431
+ ```javascript
432
+ // app.js
433
+ 'use strict';
434
+ require('securenow/register');
435
+ const { createApp, createRouter, defineEventHandler, readBody, setResponseStatus, toNodeListener } = require('h3');
436
+ const http = require('http');
437
+
438
+ const app = createApp();
439
+ const router = createRouter();
440
+
441
+ router.get('/health', defineEventHandler(() => {
442
+ return { status: 'ok' };
443
+ }));
444
+
445
+ router.post('/tasks', defineEventHandler(async (event) => {
446
+ const body = await readBody(event);
447
+ if (!body?.title) { setResponseStatus(event, 400); return { error: 'title is required' }; }
448
+ console.log('Created task:', body.title);
449
+ setResponseStatus(event, 201);
450
+ return { id: '1', title: body.title };
451
+ }));
452
+
453
+ app.use(router);
454
+
455
+ http.createServer(toNodeListener(app)).listen(3000, () => {
456
+ console.log('h3 app running on port 3000');
457
+ });
458
+ ```
459
+
460
+ ```bash
461
+ node app.js
462
+ ```
463
+
464
+ | Feature | Supported |
465
+ |---------|-----------|
466
+ | Traces | Yes |
467
+ | Logs | Yes |
468
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
469
+
470
+ ---
471
+
472
+ ### Polka
473
+
474
+ ```bash
475
+ npm install securenow polka
476
+ ```
477
+
478
+ Polka has no built-in body parser, so add a simple middleware:
479
+
480
+ ```javascript
481
+ // app.js
482
+ 'use strict';
483
+ require('securenow/register');
484
+ const polka = require('polka');
485
+
486
+ function jsonBody(req, res, next) {
487
+ if (req.method === 'GET' || req.method === 'DELETE') return next();
488
+ let data = '';
489
+ req.on('data', chunk => { data += chunk; });
490
+ req.on('end', () => {
491
+ try { req.body = JSON.parse(data); } catch { req.body = {}; }
492
+ next();
493
+ });
494
+ }
495
+
496
+ function sendJson(res, status, body) {
497
+ res.writeHead(status, { 'Content-Type': 'application/json' });
498
+ res.end(JSON.stringify(body));
499
+ }
500
+
501
+ polka()
502
+ .use(jsonBody)
503
+ .get('/health', (req, res) => sendJson(res, 200, { status: 'ok' }))
504
+ .post('/tasks', (req, res) => {
505
+ const { title } = req.body;
506
+ if (!title) return sendJson(res, 400, { error: 'title is required' });
507
+ console.log('Created task:', title);
508
+ sendJson(res, 201, { id: '1', title });
509
+ })
510
+ .listen(3000, () => {
511
+ console.log('Polka app running on port 3000');
512
+ });
513
+ ```
514
+
515
+ ```bash
516
+ node app.js
517
+ ```
518
+
519
+ | Feature | Supported |
520
+ |---------|-----------|
521
+ | Traces | Yes |
522
+ | Logs | Yes |
523
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
524
+
525
+ ---
526
+
527
+ ### Micro / Raw HTTP
528
+
529
+ For apps using the bare `http` module:
530
+
531
+ ```bash
532
+ npm install securenow
533
+ ```
534
+
535
+ ```javascript
536
+ // app.js
537
+ 'use strict';
538
+ require('securenow/register');
539
+ const http = require('http');
540
+
541
+ function sendJson(res, status, body) {
542
+ res.writeHead(status, { 'Content-Type': 'application/json' });
543
+ res.end(JSON.stringify(body));
544
+ }
545
+
546
+ function readBody(req) {
547
+ return new Promise((resolve) => {
548
+ let data = '';
549
+ req.on('data', chunk => { data += chunk; });
550
+ req.on('end', () => {
551
+ try { resolve(JSON.parse(data)); } catch { resolve({}); }
552
+ });
553
+ });
554
+ }
555
+
556
+ async function handler(req, res) {
557
+ const url = new URL(req.url, `http://${req.headers.host}`);
558
+
559
+ if (url.pathname === '/health' && req.method === 'GET') {
560
+ return sendJson(res, 200, { status: 'ok' });
561
+ }
562
+
563
+ if (url.pathname === '/tasks' && req.method === 'POST') {
564
+ const body = await readBody(req);
565
+ if (!body.title) return sendJson(res, 400, { error: 'title is required' });
566
+ console.log('Created task:', body.title);
567
+ return sendJson(res, 201, { id: '1', title: body.title });
568
+ }
569
+
570
+ sendJson(res, 404, { error: 'Not found' });
571
+ }
572
+
573
+ http.createServer(handler).listen(3000, () => {
574
+ console.log('HTTP app running on port 3000');
575
+ });
576
+ ```
577
+
578
+ ```bash
579
+ node app.js
580
+ ```
581
+
582
+ | Feature | Supported |
583
+ |---------|-----------|
584
+ | Traces | Yes |
585
+ | Logs | Yes |
586
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
587
+
588
+ ---
589
+
590
+ ### Hono
591
+
592
+ ```bash
593
+ npm install securenow hono @hono/node-server
594
+ ```
595
+
596
+ Hono uses ESM, so load SecureNow via the `-r` flag (do **not** use `require()` in `.mjs` files):
597
+
598
+ ```javascript
599
+ // app.mjs
600
+ import { serve } from '@hono/node-server';
601
+ import { Hono } from 'hono';
602
+
603
+ const app = new Hono();
604
+
605
+ app.get('/health', (c) => c.json({ status: 'ok' }));
606
+
607
+ app.post('/tasks', async (c) => {
608
+ const body = await c.req.json();
609
+ if (!body.title) return c.json({ error: 'title is required' }, 400);
610
+ console.log('Created task:', body.title);
611
+ return c.json({ id: '1', title: body.title }, 201);
612
+ });
613
+
614
+ serve({ fetch: app.fetch, port: 3000 }, () => {
615
+ console.log('Hono app running on port 3000');
616
+ });
617
+ ```
618
+
619
+ ```bash
620
+ node -r securenow/register app.mjs
621
+ ```
622
+
623
+ | Feature | Supported |
624
+ |---------|-----------|
625
+ | Traces | Yes |
626
+ | Logs | Yes |
627
+ | Body Capture | **No** — set `SECURENOW_CAPTURE_BODY=0` (stream conflict) |
628
+
629
+ ---
630
+
631
+ ### Feathers
632
+
633
+ ```bash
634
+ npm install securenow @feathersjs/feathers @feathersjs/express @feathersjs/errors
635
+ ```
636
+
637
+ Feathers uses Express as its transport, so the setup is identical:
638
+
639
+ ```javascript
640
+ // app.js
641
+ 'use strict';
642
+ require('securenow/register');
643
+ const feathers = require('@feathersjs/feathers');
644
+ const express = require('@feathersjs/express');
645
+ const errors = require('@feathersjs/errors');
646
+
647
+ class TaskService {
648
+ constructor() { this.tasks = []; this.nextId = 1; }
649
+
650
+ async find() { return this.tasks; }
651
+
652
+ async create(data) {
653
+ if (!data.title) throw new errors.BadRequest('title is required');
654
+ const task = { id: String(this.nextId++), title: data.title };
655
+ this.tasks.push(task);
656
+ console.log('Created task:', task.id);
657
+ return task;
658
+ }
659
+ }
660
+
661
+ const app = express(feathers());
662
+ app.use(express.json());
663
+ app.configure(express.rest());
664
+
665
+ app.get('/health', (req, res) => res.json({ status: 'ok' }));
666
+ app.use('/tasks', new TaskService());
667
+ app.use(express.errorHandler());
668
+
669
+ app.listen(3000, () => {
670
+ console.log('Feathers app running on port 3000');
671
+ });
672
+ ```
673
+
674
+ ```bash
675
+ node app.js
676
+ ```
677
+
678
+ | Feature | Supported |
679
+ |---------|-----------|
680
+ | Traces | Yes |
681
+ | Logs | Yes |
682
+ | Body Capture | Yes — set `SECURENOW_CAPTURE_BODY=1` |
683
+
684
+ ---
685
+
686
+ ### Next.js
687
+
688
+ ```bash
689
+ npm install securenow
690
+ ```
691
+
692
+ Create `instrumentation.ts` (or `.js`) in your project root (or `src/` if you use that layout):
693
+
694
+ ```typescript
695
+ // instrumentation.ts
696
+ export async function register() {
697
+ if (process.env.NEXT_RUNTIME === 'nodejs') {
698
+ await import('securenow/register');
699
+ }
700
+ }
701
+ ```
702
+
703
+ Add to `.env.local`:
704
+
705
+ ```env
706
+ SECURENOW_APPID=my-nextjs-app
707
+ SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
708
+ SECURENOW_LOGGING_ENABLED=1
709
+ SECURENOW_NO_UUID=1
710
+ ```
711
+
712
+ **Or scaffold it automatically:**
713
+
714
+ ```bash
715
+ npx securenow init
716
+ ```
717
+
718
+ This creates both `instrumentation.ts` and `.env.local` for you.
719
+
720
+ ```bash
721
+ npm run dev
722
+ ```
723
+
724
+ | Feature | Supported |
725
+ |---------|-----------|
726
+ | Traces | Yes |
727
+ | Logs | Yes |
728
+ | Body Capture | Yes |
729
+
730
+ See the [full Next.js guide](./NEXTJS-SETUP-COMPLETE.md) for App Router, middleware, and server actions.
731
+
732
+ ---
733
+
734
+ ## Step 4 — Verify It Works
735
+
736
+ After starting your app, you should see this in the console:
737
+
738
+ ```
739
+ [securenow] OTel SDK started → https://freetrial.securenow.ai:4318/v1/traces
740
+ [securenow] 📋 Logging: ENABLED → https://freetrial.securenow.ai:4318/v1/logs
741
+ ```
742
+
743
+ Send a test request:
744
+
745
+ ```bash
746
+ curl http://localhost:3000/health
747
+ ```
748
+
749
+ Then check traces from the CLI:
750
+
751
+ ```bash
752
+ npx securenow traces --app my-app
753
+ ```
754
+
755
+ Traces and logs should appear within seconds.
756
+
757
+ ---
758
+
759
+ ## Step 5 — CLI Command Reference
760
+
761
+ The SecureNow CLI is your terminal command center. Below is every command organized by workflow.
762
+
763
+ ### Authentication
764
+
765
+ | Command | What It Does |
766
+ |---------|-------------|
767
+ | `securenow login` | Opens browser to authenticate (global session) |
768
+ | `securenow login --token <T>` | Authenticate with a token (for CI/CD or headless servers) |
769
+ | `securenow login --local` | Save credentials to this project only (per-project session) |
770
+ | `securenow logout` | Clear stored credentials |
771
+ | `securenow logout --local` | Clear project-local credentials only |
772
+ | `securenow whoami` | Show current session (email, API URL, auth source, expiry, default app) |
773
+
774
+ **Per-project credentials:** Use `--local` to maintain separate logins for different projects on the same machine. The CLI resolves credentials in order: `SECURENOW_TOKEN` env var → project `.securenow/credentials.json` → global `~/.securenow/credentials.json`.
775
+
776
+ ### App Management
777
+
778
+ | Command | What It Does |
779
+ |---------|-------------|
780
+ | `securenow apps list` | List all your applications |
781
+ | `securenow apps create <name>` | Create a new app (interactive instance picker) |
782
+ | `securenow apps create <name> --hosts api.example.com` | Create with host binding |
783
+ | `securenow apps info <id>` | Show app details + env variables |
784
+ | `securenow apps delete <id>` | Delete an app |
785
+ | `securenow apps default <key>` | Set default app for CLI commands |
786
+ | `securenow apps discover --domain example.com` | Discover subdomains and add as apps |
787
+ | `securenow apps scan --yes` | Scan all app domains for new subdomains |
788
+
789
+ ### Observe — Traces & Logs
790
+
791
+ | Command | What It Does |
792
+ |---------|-------------|
793
+ | `securenow traces` | List recent traces |
794
+ | `securenow traces --app my-app --limit 50` | Filtered trace list |
795
+ | `securenow traces show <traceId>` | Show all spans in a trace |
796
+ | `securenow traces analyze <traceId>` | AI-powered security analysis of a trace |
797
+ | `securenow logs` | List recent logs |
798
+ | `securenow logs --app my-app --minutes 30 --level ERROR` | Filtered logs |
799
+ | `securenow logs trace <traceId>` | Show all logs for a specific trace |
800
+ | `securenow analytics --app my-app` | Response code breakdown (2xx/3xx/4xx/5xx) |
801
+ | `securenow status` | Dashboard overview (apps, alerts, protection status) |
802
+
803
+ ### Detect & Respond — Alerts, Notifications, False Positives
804
+
805
+ | Command | What It Does |
806
+ |---------|-------------|
807
+ | `securenow alerts rules` | List alert rules |
808
+ | `securenow alerts rules show <id>` | One rule (all-apps vs explicit keys) |
809
+ | `securenow alerts rules update <id> --applications-all` | All current & future apps |
810
+ | `securenow alerts rules update <id> --apps k1,k2` | Explicit app keys only |
811
+ | `securenow alerts channels` | List alert channels (email, webhook, Slack) |
812
+ | `securenow alerts history --limit 50` | View past triggered alerts |
813
+ | `securenow notifications` | List notifications |
814
+ | `securenow notifications unread` | Show unread count |
815
+ | `securenow notifications read <id>` | Mark one as read |
816
+ | `securenow notifications read-all` | Mark all as read |
817
+ | `securenow fp` / `fp list` | List FP exclusion rules |
818
+ | `securenow fp show <id>` | Rule detail (conditions, scope, match mode) |
819
+ | `securenow fp create --conditions '[...]'` | Create raw exclusion rule |
820
+ | `securenow fp create --path /api/events --method POST --path-safe standard` | Safe-value preset helper |
821
+ | `securenow fp edit <id> [--active true\|false] [--conditions '[...]']` | Edit existing rule |
822
+ | `securenow fp delete <id> [--yes]` | Delete rule |
823
+ | `securenow fp test-body '<json>' --conditions '[...]'` | Test conditions against a payload |
824
+ | `securenow fp dry-run --conditions '[...]'` | Dry-run against last 3 days of live traces |
825
+ | `securenow fp ai-fill --description "..."` | AI-generate exclusion conditions |
826
+ | `securenow fp mark <notification-id> <ip>` | Mark an IP as FP on a notification in one shot |
827
+
828
+ ### Investigate — IP Intelligence & Forensics
829
+
830
+ | Command | What It Does |
831
+ |---------|-------------|
832
+ | `securenow ip <ip-address>` | Full IP intelligence report (country, ISP, abuse score, risk factors) |
833
+ | `securenow ip traces <ip-address>` | Show all traces from a specific IP |
834
+ | `securenow forensics "<query>"` | **Chat with your data** — natural language to SQL (see below) |
835
+ | `securenow forensics library` | View saved forensic queries |
836
+ | `securenow api-map` | List all discovered API endpoints |
837
+ | `securenow api-map stats` | API map statistics |
838
+
839
+ ### Remediation — Blocklist, Allowlist & Trusted IPs
840
+
841
+ | Command | What It Does |
842
+ |---------|-------------|
843
+ | `securenow blocklist` | List all blocked IPs |
844
+ | `securenow blocklist add <ip>` | Block an IP address |
845
+ | `securenow blocklist add <cidr> --reason "brute force"` | Block a CIDR range with reason |
846
+ | `securenow blocklist remove <id>` | Unblock an IP |
847
+ | `securenow blocklist stats` | Blocklist statistics |
848
+ | `securenow allowlist` | List allowed IPs (restrict mode) |
849
+ | `securenow allowlist add <ip> --label "office" --reason "corporate VPN"` | Allow an IP |
850
+ | `securenow allowlist remove <id>` | Remove from allowlist |
851
+ | `securenow trusted` | List trusted IPs |
852
+ | `securenow trusted add <ip> --label "office"` | Add a trusted IP |
853
+ | `securenow trusted remove <id>` | Remove a trusted IP |
854
+
855
+ ### Firewall Runtime
856
+
857
+ | Command | What It Does |
858
+ |---------|-------------|
859
+ | `securenow firewall status` | Active layers, sync time, blocked count |
860
+ | `securenow firewall test-ip <ip>` | Check if an IP would be blocked |
861
+ | `securenow run --firewall-only <script>` | Preload firewall **without** OTel tracing (zero overhead) |
862
+
863
+ ### Telemetry from the Shell
864
+
865
+ Mirrors the SDK's `getLogger()` and tracing APIs for scripts, cron, and CI.
866
+
867
+ | Command | What It Does |
868
+ |---------|-------------|
869
+ | `securenow log send "<msg>" [--level info\|warn\|error] [--attrs k=v]` | Emit an OTLP log record |
870
+ | `securenow test-span [<name>]` | Emit a test span to verify collector connectivity |
871
+
872
+ ### Utilities
873
+
874
+ SDK helpers surfaced as CLI commands.
875
+
876
+ | Command | What It Does |
877
+ |---------|-------------|
878
+ | `securenow redact '<json>' [--fields f1,f2]` | Redact sensitive fields (accepts `@file.json`) |
879
+ | `securenow cidr match <ip> <cidrs>` | IP vs. CIDR list (exit 0 hit / 2 miss) |
880
+ | `securenow cidr parse <cidr>` | Parse CIDR — network, broadcast, mask, size |
881
+ | `securenow env [--json]` | Show resolved config (service name, endpoints, env vars) |
882
+ | `securenow doctor [--json]` | Probe OTLP + API endpoints, check config sanity |
883
+
884
+ ### Settings & Config
885
+
886
+ | Command | What It Does |
887
+ |---------|-------------|
888
+ | `securenow config set <key> <value>` | Set a config value |
889
+ | `securenow config get [key]` | Get a config value (or show all) |
890
+ | `securenow config path` | Show config + credentials file paths |
891
+ | `securenow instances` | List ClickHouse instances |
892
+ | `securenow instances test <id>` | Test an instance connection |
893
+ | `securenow version` | Show CLI version |
894
+
895
+ ### Global Flags
896
+
897
+ Every command supports:
898
+
899
+ | Flag | Effect |
900
+ |------|--------|
901
+ | `--json` | Output raw JSON (pipe to `jq`, scripts, etc.) |
902
+ | `--help` | Show help for any command |
903
+ | `--app <key>` | Override the default app for this command |
904
+
905
+ ---
906
+
907
+ ## Step 6 — Forensics Chat — Ask Questions in Plain English
908
+
909
+ The `securenow forensics` command lets you **ask security questions in plain English**. SecureNow translates your question to SQL, runs it against your ClickHouse traces database, and returns the results.
910
+
911
+ ### How to Use
912
+
913
+ ```bash
914
+ npx securenow forensics "your question here"
915
+ ```
916
+
917
+ ### Example Queries
918
+
919
+ **Find suspicious activity:**
920
+
921
+ ```bash
922
+ npx securenow forensics "show me all 401 responses in the last hour"
923
+ ```
924
+
925
+ **Hunt for attackers:**
926
+
927
+ ```bash
928
+ npx securenow forensics "which IPs sent the most requests in the last 24 hours"
929
+ ```
930
+
931
+ **Find slow endpoints:**
932
+
933
+ ```bash
934
+ npx securenow forensics "show the slowest API endpoints this week"
935
+ ```
936
+
937
+ **Investigate a specific IP:**
938
+
939
+ ```bash
940
+ npx securenow forensics "show all requests from 185.220.101.1 in the last 7 days"
941
+ ```
942
+
943
+ **Error analysis:**
944
+
945
+ ```bash
946
+ npx securenow forensics "count 500 errors per endpoint in the last 24 hours"
947
+ ```
948
+
949
+ **Brute force detection:**
950
+
951
+ ```bash
952
+ npx securenow forensics "find IPs that sent more than 100 POST requests to /login today"
953
+ ```
954
+
955
+ **Data exfiltration patterns:**
956
+
957
+ ```bash
958
+ npx securenow forensics "show requests with response bodies larger than 1MB"
959
+ ```
960
+
961
+ ### How It Works
962
+
963
+ 1. You type a question in English
964
+ 2. SecureNow's AI converts it to a SQL query
965
+ 3. The query runs against your ClickHouse traces database
966
+ 4. Results are displayed as a table in your terminal
967
+
968
+ The CLI shows you both the generated SQL and the results:
969
+
970
+ ```
971
+ Generated SQL
972
+
973
+ SELECT ClientIP, count() as cnt FROM traces
974
+ WHERE Timestamp > now() - INTERVAL 1 HOUR AND ResponseStatusCode = 401
975
+ GROUP BY ClientIP ORDER BY cnt DESC LIMIT 20
976
+
977
+ Results (5 rows)
978
+
979
+ ClientIP cnt
980
+ 185.220.101.1 342
981
+ 45.134.26.8 128
982
+ ...
983
+ ```
984
+
985
+ ### Save & Reuse Queries
986
+
987
+ View your saved query library:
988
+
989
+ ```bash
990
+ npx securenow forensics library
991
+ ```
992
+
993
+ ### Output as JSON
994
+
995
+ Pipe forensic results to scripts or other tools:
996
+
997
+ ```bash
998
+ npx securenow forensics "top 10 IPs by request count today" --json | jq '.result'
999
+ ```
1000
+
1001
+ ---
1002
+
1003
+ ## Step 7 — Block & Manage IPs
1004
+
1005
+ SecureNow gives you full IP lifecycle management — investigate, block, trust, and audit.
1006
+
1007
+ ### Investigate an IP
1008
+
1009
+ Before blocking, look up the IP's intelligence:
1010
+
1011
+ ```bash
1012
+ npx securenow ip 185.220.101.1
1013
+ ```
1014
+
1015
+ Output:
1016
+
1017
+ ```
1018
+ IP Intelligence: 185.220.101.1
1019
+
1020
+ Country Germany (DE)
1021
+ ISP Tor Exit Node
1022
+ Usage Type Hosting
1023
+ Abuse Score 100/100
1024
+ Malicious Yes
1025
+ Bot Yes
1026
+ Total Reports 4,521
1027
+
1028
+ Risk Factors
1029
+ • Known Tor exit node
1030
+ • High abuse confidence score
1031
+ • Associated with brute force attacks
1032
+
1033
+ Attack Types
1034
+ • SSH Brute Force
1035
+ • Web Application Attack
1036
+ • Port Scanning
1037
+ ```
1038
+
1039
+ ### See What That IP Did
1040
+
1041
+ ```bash
1042
+ npx securenow ip traces 185.220.101.1
1043
+ ```
1044
+
1045
+ Shows all traced requests from that IP — method, status code, URL, duration, and time.
1046
+
1047
+ ### Block an IP
1048
+
1049
+ ```bash
1050
+ npx securenow blocklist add 185.220.101.1 --reason "tor exit node, brute force"
1051
+ ```
1052
+
1053
+ Block a CIDR range:
1054
+
1055
+ ```bash
1056
+ npx securenow blocklist add 185.220.101.0/24 --reason "malicious subnet"
1057
+ ```
1058
+
1059
+ Block with an expiration:
1060
+
1061
+ ```bash
1062
+ npx securenow blocklist add 45.134.26.8 --reason "rate limiting" --duration 24h
1063
+ ```
1064
+
1065
+ ### View All Blocked IPs
1066
+
1067
+ ```bash
1068
+ npx securenow blocklist
1069
+ ```
1070
+
1071
+ Output:
1072
+
1073
+ ```
1074
+ ID IP/CIDR Reason Source Added Expires
1075
+ abc123... 185.220.101.1 tor exit node manual 2 hours ago permanent
1076
+ def456... 185.220.101.0/24 malicious subnet manual 1 hour ago permanent
1077
+ ghi789... 45.134.26.8 rate limiting manual 30 min ago 2024-01-16
1078
+ ```
1079
+
1080
+ ### Unblock an IP
1081
+
1082
+ ```bash
1083
+ npx securenow blocklist remove abc123
1084
+ ```
1085
+
1086
+ ### Blocklist Statistics
1087
+
1088
+ ```bash
1089
+ npx securenow blocklist stats
1090
+ ```
1091
+
1092
+ Shows total active blocks, removed blocks, manual vs automated counts, and active automation rules.
1093
+
1094
+ ### Trust an IP (Whitelist)
1095
+
1096
+ Trusted IPs bypass security detections:
1097
+
1098
+ ```bash
1099
+ npx securenow trusted add 203.0.113.50 --label "office VPN"
1100
+ ```
1101
+
1102
+ List trusted IPs:
1103
+
1104
+ ```bash
1105
+ npx securenow trusted
1106
+ ```
1107
+
1108
+ Remove a trusted IP:
1109
+
1110
+ ```bash
1111
+ npx securenow trusted remove <id>
1112
+ ```
1113
+
1114
+ ### Full Investigation → Block Workflow
1115
+
1116
+ Here is the typical workflow for handling a suspicious IP:
1117
+
1118
+ ```bash
1119
+ # 1. Check forensics for anomalies
1120
+ npx securenow forensics "IPs with more than 50 failed login attempts today"
1121
+
1122
+ # 2. Pick a suspicious IP and investigate
1123
+ npx securenow ip 185.220.101.1
1124
+
1125
+ # 3. See exactly what it did
1126
+ npx securenow ip traces 185.220.101.1
1127
+
1128
+ # 4. Block it
1129
+ npx securenow blocklist add 185.220.101.1 --reason "brute force login attempts"
1130
+
1131
+ # 5. Verify it's blocked
1132
+ npx securenow blocklist
1133
+ ```
1134
+
1135
+ ### Enforce the Blocklist on Your App (Firewall)
1136
+
1137
+ Once you've built a blocklist, enforce it at your application layer — automatically, with zero code changes:
1138
+
1139
+ ```bash
1140
+ # Add your API key to .env
1141
+ SECURENOW_API_KEY=snk_live_abc123...
1142
+ ```
1143
+
1144
+ Restart your app. The firewall syncs the blocklist every 60 seconds and blocks matching IPs with a 403 response:
1145
+
1146
+ ```
1147
+ [securenow] Firewall: ENABLED
1148
+ [securenow] Firewall: Layer 1 (HTTP 403) active
1149
+ [securenow] Firewall: synced 142 blocked IPs
1150
+ ```
1151
+
1152
+ Enable additional layers for defense in depth:
1153
+
1154
+ ```bash
1155
+ # TCP-level blocking (zero bytes sent back)
1156
+ SECURENOW_FIREWALL_TCP=1
1157
+
1158
+ # OS-level blocking (iptables/nftables, Linux only)
1159
+ SECURENOW_FIREWALL_IPTABLES=1
1160
+
1161
+ # Cloud WAF blocking (Cloudflare, AWS WAF, GCP Cloud Armor)
1162
+ SECURENOW_FIREWALL_CLOUD=cloudflare
1163
+ ```
1164
+
1165
+ Check firewall status:
1166
+
1167
+ ```bash
1168
+ npx securenow firewall status
1169
+ npx securenow firewall test-ip 185.220.101.1
1170
+ ```
1171
+
1172
+ See the [Firewall Guide](FIREWALL-GUIDE.md) for the full reference.
1173
+
1174
+ ---
1175
+
1176
+ ## Step 8 — Monitor, Detect & Respond
1177
+
1178
+ ### Daily Monitoring
1179
+
1180
+ ```bash
1181
+ # Quick overview of all your apps
1182
+ npx securenow status
1183
+
1184
+ # Check for unread alerts
1185
+ npx securenow notifications unread
1186
+
1187
+ # List open security issues
1188
+ npx securenow issues --status open
1189
+ ```
1190
+
1191
+ ### Respond to an Issue
1192
+
1193
+ ```bash
1194
+ # Read the full issue detail (includes AI analysis)
1195
+ npx securenow issues show <id>
1196
+
1197
+ # If it's resolved, mark it
1198
+ npx securenow issues resolve <id>
1199
+ ```
1200
+
1201
+ ### AI Trace Analysis
1202
+
1203
+ Let SecureNow's AI analyze a suspicious trace for security issues:
1204
+
1205
+ ```bash
1206
+ npx securenow traces analyze <traceId>
1207
+ ```
1208
+
1209
+ Returns a summary, risk level, specific security issues found, and recommended actions.
1210
+
1211
+ ### Set Up Alerts
1212
+
1213
+ Configure alert rules and channels from the [dashboard](https://app.securenow.ai/dashboard), then monitor from the CLI:
1214
+
1215
+ ```bash
1216
+ # List your alert rules
1217
+ npx securenow alerts rules
1218
+
1219
+ # Show one rule / set application scope (all apps vs explicit keys)
1220
+ npx securenow alerts rules show <rule-id>
1221
+ npx securenow alerts rules update <rule-id> --applications-all
1222
+ npx securenow alerts rules update <rule-id> --apps key1,key2
1223
+
1224
+ # List alert channels (email, Slack, webhook)
1225
+ npx securenow alerts channels
1226
+
1227
+ # View alert history
1228
+ npx securenow alerts history --limit 20
1229
+ ```
1230
+
1231
+ ---
1232
+
1233
+ ## Deployment
1234
+
1235
+ ### PM2 Setup (All Frameworks)
1236
+
1237
+ ```javascript
1238
+ // ecosystem.config.cjs
1239
+ module.exports = {
1240
+ apps: [{
1241
+ name: 'my-app',
1242
+ script: './app.js',
1243
+ node_args: '-r securenow/register',
1244
+ env: {
1245
+ SECURENOW_APPID: 'my-app',
1246
+ SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
1247
+ SECURENOW_LOGGING_ENABLED: '1',
1248
+ SECURENOW_NO_UUID: '1',
1249
+ SECURENOW_CAPTURE_BODY: '1',
1250
+ PORT: 3000,
1251
+ }
1252
+ }]
1253
+ };
1254
+ ```
1255
+
1256
+ ```bash
1257
+ pm2 start ecosystem.config.cjs
1258
+ ```
1259
+
1260
+ **NestJS (TypeScript):**
1261
+
1262
+ ```javascript
1263
+ {
1264
+ name: 'my-nestjs-app',
1265
+ script: 'dist/main.js',
1266
+ node_args: '-r ./instrument.js',
1267
+ env: { /* same as above */ }
1268
+ }
1269
+ ```
1270
+
1271
+ **Hono (ESM `.mjs`):**
1272
+
1273
+ ```javascript
1274
+ {
1275
+ name: 'my-hono-app',
1276
+ script: 'app.mjs',
1277
+ node_args: '-r securenow/register',
1278
+ env: {
1279
+ SECURENOW_CAPTURE_BODY: '0', // Required for Hono
1280
+ /* ... other vars ... */
1281
+ }
1282
+ }
1283
+ ```
1284
+
1285
+ ### Docker
1286
+
1287
+ ```dockerfile
1288
+ FROM node:20-alpine
1289
+ WORKDIR /app
1290
+ COPY package*.json ./
1291
+ RUN npm install
1292
+ COPY . .
1293
+
1294
+ ENV SECURENOW_APPID=my-app
1295
+ ENV SECURENOW_INSTANCE=https://collector:4318
1296
+ ENV SECURENOW_LOGGING_ENABLED=1
1297
+ ENV SECURENOW_NO_UUID=1
1298
+
1299
+ EXPOSE 3000
1300
+ CMD ["node", "-r", "securenow/register", "app.js"]
1301
+ ```
1302
+
1303
+ ---
1304
+
1305
+ ## Compatibility Matrix
1306
+
1307
+ | Framework | Traces | Logs | Body Capture | Init Method | Notes |
1308
+ |-----------|--------|------|--------------|-------------|-------|
1309
+ | Express | Yes | Yes | Yes | `require()` or `-r` | Fully compatible |
1310
+ | Fastify | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
1311
+ | Koa | Yes | Yes | Yes | `require()` or `-r` | Needs `koa-bodyparser` |
1312
+ | NestJS | Yes | Yes | Yes | `instrument.js` + `-r ./instrument.js` | Create `instrument.js` with `require('securenow/register')` |
1313
+ | Hapi | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
1314
+ | h3 | Yes | Yes | Yes | `require()` or `-r` | Uses `toNodeListener()` |
1315
+ | Polka | Yes | Yes | Yes | `require()` or `-r` | Needs manual body parser |
1316
+ | Micro/HTTP | Yes | Yes | Yes | `require()` or `-r` | Raw `http.createServer` |
1317
+ | Hono | Yes | Yes | **No** | `-r` flag only (ESM) | Set `SECURENOW_CAPTURE_BODY=0` |
1318
+ | Feathers | Yes | Yes | Yes | `require()` or `-r` | Express transport |
1319
+ | Next.js | Yes | Yes | Yes | `instrumentation.ts` | Use `securenow init` |
1320
+
1321
+ ---
1322
+
1323
+ ## Troubleshooting
1324
+
1325
+ ### Traces not appearing
1326
+
1327
+ 1. Verify `SECURENOW_APPID` and `SECURENOW_INSTANCE` are set
1328
+ 2. Set `SECURENOW_NO_UUID=1` so the dashboard matches your app key exactly
1329
+ 3. Enable debug logging: `OTEL_LOG_LEVEL=debug node -r securenow/register app.js`
1330
+
1331
+ ### Logs not appearing
1332
+
1333
+ 1. Confirm `SECURENOW_LOGGING_ENABLED=1` is set
1334
+ 2. Check that startup output shows `📋 Logging: ENABLED`
1335
+ 3. Any `console.log` / `console.error` in your app automatically becomes an OTLP log record
1336
+
1337
+ ### ESM apps (.mjs / "type": "module")
1338
+
1339
+ Use `NODE_OPTIONS="-r securenow/register"` or `node -r securenow/register app.mjs`.
1340
+ Do **not** add `require('securenow/register')` inside `.mjs` files.
1341
+
1342
+ ### Body capture crashes / empty payloads
1343
+
1344
+ Set `SECURENOW_CAPTURE_BODY=0` for Fastify, Hapi, and Hono. These frameworks use custom stream handling that conflicts with the body capture hook.
1345
+
1346
+ ### CLI says "Not logged in"
1347
+
1348
+ ```bash
1349
+ npx securenow login
1350
+ ```
1351
+
1352
+ Or re-authenticate with a token:
1353
+
1354
+ ```bash
1355
+ npx securenow login --token <YOUR_TOKEN>
1356
+ ```
1357
+
1358
+ Or set the env var directly:
1359
+
1360
+ ```bash
1361
+ SECURENOW_TOKEN=<YOUR_JWT> npx securenow whoami
1362
+ ```
1363
+
1364
+ ### CLI says "Session expired"
1365
+
1366
+ Tokens expire after a set period. Re-run `securenow login` to get a fresh session. Use `securenow whoami` to check which credential source is active.
1367
+
1368
+ ---
1369
+
1370
+ ## Complete Documentation
1371
+
1372
+ - [Express Guide](./EXPRESS-SETUP-GUIDE.md)
1373
+ - [Next.js Guide](./NEXTJS-SETUP-COMPLETE.md)
1374
+ - [Logging Guide](./LOGGING-GUIDE.md)
1375
+ - [Environment Variables](./ENVIRONMENT-VARIABLES.md)
1376
+ - [Body Capture](./REQUEST-BODY-CAPTURE.md)
1377
+ - [NPM README](../NPM_README.md)