securenow 5.5.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,455 +1,1282 @@
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](#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 |
768
+ | `securenow login --token <T>` | Authenticate with a token (for CI/CD or headless servers) |
769
+ | `securenow logout` | Clear stored credentials |
770
+ | `securenow whoami` | Show current session (email, API URL, expiry, default app) |
771
+
772
+ ### App Management
773
+
774
+ | Command | What It Does |
775
+ |---------|-------------|
776
+ | `securenow apps list` | List all your applications |
777
+ | `securenow apps create <name>` | Create a new app (interactive instance picker) |
778
+ | `securenow apps create <name> --hosts api.example.com` | Create with host binding |
779
+ | `securenow apps info <id>` | Show app details + env variables |
780
+ | `securenow apps delete <id>` | Delete an app |
781
+ | `securenow apps default <key>` | Set default app for CLI commands |
782
+ | `securenow apps discover --domain example.com` | Discover subdomains and add as apps |
783
+ | `securenow apps scan --yes` | Scan all app domains for new subdomains |
784
+
785
+ ### Observe — Traces & Logs
786
+
787
+ | Command | What It Does |
788
+ |---------|-------------|
789
+ | `securenow traces` | List recent traces |
790
+ | `securenow traces --app my-app --limit 50` | Filtered trace list |
791
+ | `securenow traces show <traceId>` | Show all spans in a trace |
792
+ | `securenow traces analyze <traceId>` | AI-powered security analysis of a trace |
793
+ | `securenow logs` | List recent logs |
794
+ | `securenow logs --app my-app --minutes 30 --level ERROR` | Filtered logs |
795
+ | `securenow logs trace <traceId>` | Show all logs for a specific trace |
796
+ | `securenow analytics --app my-app` | Response code breakdown (2xx/3xx/4xx/5xx) |
797
+ | `securenow status` | Dashboard overview (apps, alerts, protection status) |
798
+
799
+ ### Detect & Respond — Issues, Alerts, Notifications
800
+
801
+ | Command | What It Does |
802
+ |---------|-------------|
803
+ | `securenow issues` | List security issues |
804
+ | `securenow issues --status open` | Filter by status |
805
+ | `securenow issues show <id>` | Full issue detail + AI analysis |
806
+ | `securenow issues resolve <id>` | Mark issue as resolved |
807
+ | `securenow alerts rules` | List alert rules |
808
+ | `securenow alerts channels` | List alert channels (email, webhook, Slack) |
809
+ | `securenow alerts history --limit 50` | View past triggered alerts |
810
+ | `securenow notifications` | List notifications |
811
+ | `securenow notifications unread` | Show unread count |
812
+ | `securenow notifications read <id>` | Mark one as read |
813
+ | `securenow notifications read-all` | Mark all as read |
814
+
815
+ ### Investigate — IP Intelligence & Forensics
816
+
817
+ | Command | What It Does |
818
+ |---------|-------------|
819
+ | `securenow ip <ip-address>` | Full IP intelligence report (country, ISP, abuse score, risk factors) |
820
+ | `securenow ip traces <ip-address>` | Show all traces from a specific IP |
821
+ | `securenow forensics "<query>"` | **Chat with your data** — natural language to SQL (see below) |
822
+ | `securenow forensics library` | View saved forensic queries |
823
+ | `securenow api-map` | List all discovered API endpoints |
824
+ | `securenow api-map stats` | API map statistics |
825
+
826
+ ### Remediation — Blocklist & Trusted IPs
827
+
828
+ | Command | What It Does |
829
+ |---------|-------------|
830
+ | `securenow blocklist` | List all blocked IPs |
831
+ | `securenow blocklist add <ip>` | Block an IP address |
832
+ | `securenow blocklist add <cidr> --reason "brute force"` | Block a CIDR range with reason |
833
+ | `securenow blocklist remove <id>` | Unblock an IP |
834
+ | `securenow blocklist stats` | Blocklist statistics |
835
+ | `securenow trusted` | List trusted IPs |
836
+ | `securenow trusted add <ip> --label "office"` | Add a trusted IP |
837
+ | `securenow trusted remove <id>` | Remove a trusted IP |
838
+
839
+ ### Settings & Config
840
+
841
+ | Command | What It Does |
842
+ |---------|-------------|
843
+ | `securenow config set <key> <value>` | Set a config value |
844
+ | `securenow config get [key]` | Get a config value (or show all) |
845
+ | `securenow config path` | Show config + credentials file paths |
846
+ | `securenow instances` | List ClickHouse instances |
847
+ | `securenow instances test <id>` | Test an instance connection |
848
+ | `securenow version` | Show CLI version |
849
+
850
+ ### Global Flags
851
+
852
+ Every command supports:
853
+
854
+ | Flag | Effect |
855
+ |------|--------|
856
+ | `--json` | Output raw JSON (pipe to `jq`, scripts, etc.) |
857
+ | `--help` | Show help for any command |
858
+ | `--app <key>` | Override the default app for this command |
859
+
860
+ ---
861
+
862
+ ## Step 6 — Forensics Chat — Ask Questions in Plain English
863
+
864
+ 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.
865
+
866
+ ### How to Use
867
+
868
+ ```bash
869
+ npx securenow forensics "your question here"
870
+ ```
871
+
872
+ ### Example Queries
873
+
874
+ **Find suspicious activity:**
875
+
876
+ ```bash
877
+ npx securenow forensics "show me all 401 responses in the last hour"
878
+ ```
879
+
880
+ **Hunt for attackers:**
881
+
882
+ ```bash
883
+ npx securenow forensics "which IPs sent the most requests in the last 24 hours"
884
+ ```
885
+
886
+ **Find slow endpoints:**
887
+
888
+ ```bash
889
+ npx securenow forensics "show the slowest API endpoints this week"
890
+ ```
891
+
892
+ **Investigate a specific IP:**
893
+
894
+ ```bash
895
+ npx securenow forensics "show all requests from 185.220.101.1 in the last 7 days"
896
+ ```
897
+
898
+ **Error analysis:**
899
+
900
+ ```bash
901
+ npx securenow forensics "count 500 errors per endpoint in the last 24 hours"
902
+ ```
903
+
904
+ **Brute force detection:**
905
+
906
+ ```bash
907
+ npx securenow forensics "find IPs that sent more than 100 POST requests to /login today"
908
+ ```
909
+
910
+ **Data exfiltration patterns:**
911
+
912
+ ```bash
913
+ npx securenow forensics "show requests with response bodies larger than 1MB"
914
+ ```
915
+
916
+ ### How It Works
917
+
918
+ 1. You type a question in English
919
+ 2. SecureNow's AI converts it to a SQL query
920
+ 3. The query runs against your ClickHouse traces database
921
+ 4. Results are displayed as a table in your terminal
922
+
923
+ The CLI shows you both the generated SQL and the results:
924
+
925
+ ```
926
+ Generated SQL
927
+
928
+ SELECT ClientIP, count() as cnt FROM traces
929
+ WHERE Timestamp > now() - INTERVAL 1 HOUR AND ResponseStatusCode = 401
930
+ GROUP BY ClientIP ORDER BY cnt DESC LIMIT 20
931
+
932
+ Results (5 rows)
933
+
934
+ ClientIP cnt
935
+ 185.220.101.1 342
936
+ 45.134.26.8 128
937
+ ...
938
+ ```
939
+
940
+ ### Save & Reuse Queries
941
+
942
+ View your saved query library:
943
+
944
+ ```bash
945
+ npx securenow forensics library
946
+ ```
947
+
948
+ ### Output as JSON
949
+
950
+ Pipe forensic results to scripts or other tools:
951
+
952
+ ```bash
953
+ npx securenow forensics "top 10 IPs by request count today" --json | jq '.result'
954
+ ```
955
+
956
+ ---
957
+
958
+ ## Step 7 — Block & Manage IPs
959
+
960
+ SecureNow gives you full IP lifecycle management — investigate, block, trust, and audit.
961
+
962
+ ### Investigate an IP
963
+
964
+ Before blocking, look up the IP's intelligence:
965
+
966
+ ```bash
967
+ npx securenow ip 185.220.101.1
968
+ ```
969
+
970
+ Output:
971
+
972
+ ```
973
+ IP Intelligence: 185.220.101.1
974
+
975
+ Country Germany (DE)
976
+ ISP Tor Exit Node
977
+ Usage Type Hosting
978
+ Abuse Score 100/100
979
+ Malicious Yes
980
+ Bot Yes
981
+ Total Reports 4,521
982
+
983
+ Risk Factors
984
+ • Known Tor exit node
985
+ • High abuse confidence score
986
+ • Associated with brute force attacks
987
+
988
+ Attack Types
989
+ • SSH Brute Force
990
+ • Web Application Attack
991
+ • Port Scanning
992
+ ```
993
+
994
+ ### See What That IP Did
995
+
996
+ ```bash
997
+ npx securenow ip traces 185.220.101.1
998
+ ```
999
+
1000
+ Shows all traced requests from that IP — method, status code, URL, duration, and time.
1001
+
1002
+ ### Block an IP
1003
+
1004
+ ```bash
1005
+ npx securenow blocklist add 185.220.101.1 --reason "tor exit node, brute force"
1006
+ ```
1007
+
1008
+ Block a CIDR range:
1009
+
1010
+ ```bash
1011
+ npx securenow blocklist add 185.220.101.0/24 --reason "malicious subnet"
1012
+ ```
1013
+
1014
+ Block with an expiration:
1015
+
1016
+ ```bash
1017
+ npx securenow blocklist add 45.134.26.8 --reason "rate limiting" --duration 24h
1018
+ ```
1019
+
1020
+ ### View All Blocked IPs
1021
+
1022
+ ```bash
1023
+ npx securenow blocklist
1024
+ ```
1025
+
1026
+ Output:
1027
+
1028
+ ```
1029
+ ID IP/CIDR Reason Source Added Expires
1030
+ abc123... 185.220.101.1 tor exit node manual 2 hours ago permanent
1031
+ def456... 185.220.101.0/24 malicious subnet manual 1 hour ago permanent
1032
+ ghi789... 45.134.26.8 rate limiting manual 30 min ago 2024-01-16
1033
+ ```
1034
+
1035
+ ### Unblock an IP
1036
+
1037
+ ```bash
1038
+ npx securenow blocklist remove abc123
1039
+ ```
1040
+
1041
+ ### Blocklist Statistics
1042
+
1043
+ ```bash
1044
+ npx securenow blocklist stats
1045
+ ```
1046
+
1047
+ Shows total active blocks, removed blocks, manual vs automated counts, and active automation rules.
1048
+
1049
+ ### Trust an IP (Whitelist)
1050
+
1051
+ Trusted IPs bypass security detections:
1052
+
1053
+ ```bash
1054
+ npx securenow trusted add 203.0.113.50 --label "office VPN"
1055
+ ```
1056
+
1057
+ List trusted IPs:
1058
+
1059
+ ```bash
1060
+ npx securenow trusted
1061
+ ```
1062
+
1063
+ Remove a trusted IP:
1064
+
1065
+ ```bash
1066
+ npx securenow trusted remove <id>
1067
+ ```
1068
+
1069
+ ### Full Investigation → Block Workflow
1070
+
1071
+ Here is the typical workflow for handling a suspicious IP:
1072
+
1073
+ ```bash
1074
+ # 1. Check forensics for anomalies
1075
+ npx securenow forensics "IPs with more than 50 failed login attempts today"
1076
+
1077
+ # 2. Pick a suspicious IP and investigate
1078
+ npx securenow ip 185.220.101.1
1079
+
1080
+ # 3. See exactly what it did
1081
+ npx securenow ip traces 185.220.101.1
1082
+
1083
+ # 4. Block it
1084
+ npx securenow blocklist add 185.220.101.1 --reason "brute force login attempts"
1085
+
1086
+ # 5. Verify it's blocked
1087
+ npx securenow blocklist
1088
+ ```
1089
+
1090
+ ---
1091
+
1092
+ ## Step 8 — Monitor, Detect & Respond
1093
+
1094
+ ### Daily Monitoring
1095
+
1096
+ ```bash
1097
+ # Quick overview of all your apps
1098
+ npx securenow status
1099
+
1100
+ # Check for unread alerts
1101
+ npx securenow notifications unread
1102
+
1103
+ # List open security issues
1104
+ npx securenow issues --status open
1105
+ ```
1106
+
1107
+ ### Respond to an Issue
1108
+
1109
+ ```bash
1110
+ # Read the full issue detail (includes AI analysis)
1111
+ npx securenow issues show <id>
1112
+
1113
+ # If it's resolved, mark it
1114
+ npx securenow issues resolve <id>
1115
+ ```
1116
+
1117
+ ### AI Trace Analysis
1118
+
1119
+ Let SecureNow's AI analyze a suspicious trace for security issues:
1120
+
1121
+ ```bash
1122
+ npx securenow traces analyze <traceId>
1123
+ ```
1124
+
1125
+ Returns a summary, risk level, specific security issues found, and recommended actions.
1126
+
1127
+ ### Set Up Alerts
1128
+
1129
+ Configure alert rules and channels from the [dashboard](https://app.securenow.ai/dashboard), then monitor from the CLI:
1130
+
1131
+ ```bash
1132
+ # List your alert rules
1133
+ npx securenow alerts rules
1134
+
1135
+ # List alert channels (email, Slack, webhook)
1136
+ npx securenow alerts channels
1137
+
1138
+ # View alert history
1139
+ npx securenow alerts history --limit 20
1140
+ ```
1141
+
1142
+ ---
1143
+
1144
+ ## Deployment
1145
+
1146
+ ### PM2 Setup (All Frameworks)
1147
+
1148
+ ```javascript
1149
+ // ecosystem.config.cjs
1150
+ module.exports = {
1151
+ apps: [{
1152
+ name: 'my-app',
1153
+ script: './app.js',
1154
+ node_args: '-r securenow/register',
1155
+ env: {
1156
+ SECURENOW_APPID: 'my-app',
1157
+ SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
1158
+ SECURENOW_LOGGING_ENABLED: '1',
1159
+ SECURENOW_NO_UUID: '1',
1160
+ SECURENOW_CAPTURE_BODY: '1',
1161
+ PORT: 3000,
1162
+ }
1163
+ }]
1164
+ };
1165
+ ```
1166
+
1167
+ ```bash
1168
+ pm2 start ecosystem.config.cjs
1169
+ ```
1170
+
1171
+ **NestJS (TypeScript):**
1172
+
1173
+ ```javascript
1174
+ {
1175
+ name: 'my-nestjs-app',
1176
+ script: 'dist/main.js',
1177
+ node_args: '-r ./instrument.js',
1178
+ env: { /* same as above */ }
1179
+ }
1180
+ ```
1181
+
1182
+ **Hono (ESM `.mjs`):**
1183
+
1184
+ ```javascript
1185
+ {
1186
+ name: 'my-hono-app',
1187
+ script: 'app.mjs',
1188
+ node_args: '-r securenow/register',
1189
+ env: {
1190
+ SECURENOW_CAPTURE_BODY: '0', // Required for Hono
1191
+ /* ... other vars ... */
1192
+ }
1193
+ }
1194
+ ```
1195
+
1196
+ ### Docker
1197
+
1198
+ ```dockerfile
1199
+ FROM node:20-alpine
1200
+ WORKDIR /app
1201
+ COPY package*.json ./
1202
+ RUN npm install
1203
+ COPY . .
1204
+
1205
+ ENV SECURENOW_APPID=my-app
1206
+ ENV SECURENOW_INSTANCE=https://collector:4318
1207
+ ENV SECURENOW_LOGGING_ENABLED=1
1208
+ ENV SECURENOW_NO_UUID=1
1209
+
1210
+ EXPOSE 3000
1211
+ CMD ["node", "-r", "securenow/register", "app.js"]
1212
+ ```
1213
+
1214
+ ---
1215
+
1216
+ ## Compatibility Matrix
1217
+
1218
+ | Framework | Traces | Logs | Body Capture | Init Method | Notes |
1219
+ |-----------|--------|------|--------------|-------------|-------|
1220
+ | Express | Yes | Yes | Yes | `require()` or `-r` | Fully compatible |
1221
+ | Fastify | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
1222
+ | Koa | Yes | Yes | Yes | `require()` or `-r` | Needs `koa-bodyparser` |
1223
+ | NestJS | Yes | Yes | Yes | `instrument.js` + `-r ./instrument.js` | Create `instrument.js` with `require('securenow/register')` |
1224
+ | Hapi | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
1225
+ | h3 | Yes | Yes | Yes | `require()` or `-r` | Uses `toNodeListener()` |
1226
+ | Polka | Yes | Yes | Yes | `require()` or `-r` | Needs manual body parser |
1227
+ | Micro/HTTP | Yes | Yes | Yes | `require()` or `-r` | Raw `http.createServer` |
1228
+ | Hono | Yes | Yes | **No** | `-r` flag only (ESM) | Set `SECURENOW_CAPTURE_BODY=0` |
1229
+ | Feathers | Yes | Yes | Yes | `require()` or `-r` | Express transport |
1230
+ | Next.js | Yes | Yes | Yes | `instrumentation.ts` | Use `securenow init` |
1231
+
1232
+ ---
1233
+
1234
+ ## Troubleshooting
1235
+
1236
+ ### Traces not appearing
1237
+
1238
+ 1. Verify `SECURENOW_APPID` and `SECURENOW_INSTANCE` are set
1239
+ 2. Set `SECURENOW_NO_UUID=1` so the dashboard matches your app key exactly
1240
+ 3. Enable debug logging: `OTEL_LOG_LEVEL=debug node -r securenow/register app.js`
1241
+
1242
+ ### Logs not appearing
1243
+
1244
+ 1. Confirm `SECURENOW_LOGGING_ENABLED=1` is set
1245
+ 2. Check that startup output shows `📋 Logging: ENABLED`
1246
+ 3. Any `console.log` / `console.error` in your app automatically becomes an OTLP log record
1247
+
1248
+ ### ESM apps (.mjs / "type": "module")
1249
+
1250
+ Use `NODE_OPTIONS="-r securenow/register"` or `node -r securenow/register app.mjs`.
1251
+ Do **not** add `require('securenow/register')` inside `.mjs` files.
1252
+
1253
+ ### Body capture crashes / empty payloads
1254
+
1255
+ Set `SECURENOW_CAPTURE_BODY=0` for Fastify, Hapi, and Hono. These frameworks use custom stream handling that conflicts with the body capture hook.
1256
+
1257
+ ### CLI says "Not logged in"
1258
+
1259
+ ```bash
1260
+ npx securenow login
1261
+ ```
1262
+
1263
+ Or re-authenticate with a token:
1264
+
1265
+ ```bash
1266
+ npx securenow login --token <YOUR_TOKEN>
1267
+ ```
1268
+
1269
+ ### CLI says "Session expired"
1270
+
1271
+ Tokens expire after a set period. Re-run `securenow login` to get a fresh session.
1272
+
1273
+ ---
1274
+
1275
+ ## Complete Documentation
1276
+
1277
+ - [Express Guide](./EXPRESS-SETUP-GUIDE.md)
1278
+ - [Next.js Guide](./NEXTJS-SETUP-COMPLETE.md)
1279
+ - [Logging Guide](./LOGGING-GUIDE.md)
1280
+ - [Environment Variables](./ENVIRONMENT-VARIABLES.md)
1281
+ - [Body Capture](./REQUEST-BODY-CAPTURE.md)
1282
+ - [NPM README](../NPM_README.md)