securenow 5.18.0 → 6.0.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.
- package/LICENSE +15 -0
- package/README.md +40 -239
- package/cli.js +455 -415
- package/console-instrumentation.js +136 -147
- package/docs/ALL-FRAMEWORKS-QUICKSTART.md +455 -1339
- package/docs/ARCHITECTURE.md +3 -3
- package/docs/AUTO-BODY-CAPTURE.md +1 -1
- package/docs/AUTO-SETUP.md +4 -4
- package/docs/AUTOMATIC-IP-CAPTURE.md +5 -5
- package/docs/BODY-CAPTURE-QUICKSTART.md +2 -2
- package/docs/CHANGELOG-NEXTJS.md +1 -1
- package/docs/CUSTOMER-GUIDE.md +16 -16
- package/docs/EASIEST-SETUP.md +5 -5
- package/docs/ENVIRONMENT-VARIABLES.md +652 -880
- package/docs/EXPRESS-BODY-CAPTURE.md +12 -13
- package/docs/EXPRESS-SETUP-GUIDE.md +720 -719
- package/docs/INDEX.md +4 -22
- package/docs/LOGGING-GUIDE.md +708 -701
- package/docs/LOGGING-QUICKSTART.md +239 -234
- package/docs/NEXTJS-BODY-CAPTURE.md +2 -2
- package/docs/NEXTJS-GUIDE.md +14 -14
- package/docs/NEXTJS-QUICKSTART.md +1 -1
- package/docs/NEXTJS-WRAPPER-APPROACH.md +1 -1
- package/docs/QUICKSTART-BODY-CAPTURE.md +2 -2
- package/docs/REDACTION-EXAMPLES.md +1 -1
- package/docs/REQUEST-BODY-CAPTURE.md +10 -19
- package/docs/VERCEL-OTEL-MIGRATION.md +3 -3
- package/examples/README.md +6 -6
- package/examples/instrumentation-with-auto-capture.ts +1 -1
- package/examples/nextjs-env-example.txt +2 -2
- package/examples/nextjs-instrumentation.js +1 -1
- package/examples/nextjs-instrumentation.ts +1 -1
- package/examples/nextjs-with-logging-example.md +6 -6
- package/examples/nextjs-with-options.ts +1 -1
- package/examples/test-nextjs-setup.js +1 -1
- package/nextjs-auto-capture.js +207 -199
- package/nextjs-middleware.js +181 -186
- package/nextjs-webpack-config.js +53 -88
- package/nextjs-wrapper.js +158 -158
- package/nextjs.d.ts +1 -1
- package/nextjs.js +135 -190
- package/package.json +45 -67
- package/postinstall.js +6 -6
- package/register.d.ts +1 -1
- package/register.js +4 -39
- package/tracing.d.ts +1 -2
- package/tracing.js +22 -287
- package/web-vite.mjs +156 -239
- package/CONSUMING-APPS-GUIDE.md +0 -455
- package/NPM_README.md +0 -1933
- package/SKILL-API.md +0 -600
- package/SKILL-CLI.md +0 -409
- package/cidr.js +0 -83
- package/cli/apps.js +0 -585
- package/cli/auth.js +0 -280
- package/cli/client.js +0 -115
- package/cli/config.js +0 -173
- package/cli/firewall.js +0 -100
- package/cli/fp.js +0 -638
- package/cli/init.js +0 -201
- package/cli/monitor.js +0 -440
- package/cli/run.js +0 -133
- package/cli/security.js +0 -1064
- package/cli/ui.js +0 -386
- package/docs/API-KEYS-GUIDE.md +0 -233
- package/docs/AUTO-SETUP-SUMMARY.md +0 -331
- package/docs/BODY-CAPTURE-FIX.md +0 -261
- package/docs/COMPLETION-REPORT.md +0 -408
- package/docs/FINAL-SOLUTION.md +0 -335
- package/docs/FIREWALL-GUIDE.md +0 -426
- package/docs/IMPLEMENTATION-SUMMARY.md +0 -410
- package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +0 -323
- package/docs/NEXTJS-SETUP-COMPLETE.md +0 -795
- package/docs/NUXT-GUIDE.md +0 -166
- package/docs/SOLUTION-SUMMARY.md +0 -312
- package/firewall-cloud.js +0 -212
- package/firewall-iptables.js +0 -139
- package/firewall-only.js +0 -38
- package/firewall-tcp.js +0 -74
- package/firewall.js +0 -720
- package/free-trial-banner.js +0 -174
- package/nuxt-server-plugin.mjs +0 -423
- package/nuxt.d.ts +0 -60
- package/nuxt.mjs +0 -75
- package/resolve-ip.js +0 -77
|
@@ -1,1339 +1,455 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
##
|
|
8
|
-
|
|
9
|
-
1
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
---
|
|
44
|
-
|
|
45
|
-
##
|
|
46
|
-
|
|
47
|
-
###
|
|
48
|
-
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
app
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
```bash
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
```javascript
|
|
255
|
-
//
|
|
256
|
-
'
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
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 — Issues, Alerts, Notifications
|
|
804
|
-
|
|
805
|
-
| Command | What It Does |
|
|
806
|
-
|---------|-------------|
|
|
807
|
-
| `securenow issues` | List security issues |
|
|
808
|
-
| `securenow issues --status open` | Filter by status |
|
|
809
|
-
| `securenow issues show <id>` | Full issue detail + AI analysis |
|
|
810
|
-
| `securenow issues resolve <id>` | Mark issue as resolved |
|
|
811
|
-
| `securenow alerts rules` | List alert rules |
|
|
812
|
-
| `securenow alerts rules show <id>` | One rule (all-apps vs explicit keys) |
|
|
813
|
-
| `securenow alerts rules update <id> --applications-all` | All current & future apps |
|
|
814
|
-
| `securenow alerts rules update <id> --apps k1,k2` | Explicit app keys only |
|
|
815
|
-
| `securenow alerts channels` | List alert channels (email, webhook, Slack) |
|
|
816
|
-
| `securenow alerts history --limit 50` | View past triggered alerts |
|
|
817
|
-
| `securenow notifications` | List notifications |
|
|
818
|
-
| `securenow notifications unread` | Show unread count |
|
|
819
|
-
| `securenow notifications read <id>` | Mark one as read |
|
|
820
|
-
| `securenow notifications read-all` | Mark all as read |
|
|
821
|
-
|
|
822
|
-
### Investigate — IP Intelligence & Forensics
|
|
823
|
-
|
|
824
|
-
| Command | What It Does |
|
|
825
|
-
|---------|-------------|
|
|
826
|
-
| `securenow ip <ip-address>` | Full IP intelligence report (country, ISP, abuse score, risk factors) |
|
|
827
|
-
| `securenow ip traces <ip-address>` | Show all traces from a specific IP |
|
|
828
|
-
| `securenow forensics "<query>"` | **Chat with your data** — natural language to SQL (see below) |
|
|
829
|
-
| `securenow forensics library` | View saved forensic queries |
|
|
830
|
-
| `securenow api-map` | List all discovered API endpoints |
|
|
831
|
-
| `securenow api-map stats` | API map statistics |
|
|
832
|
-
|
|
833
|
-
### Remediation — Blocklist & Trusted IPs
|
|
834
|
-
|
|
835
|
-
| Command | What It Does |
|
|
836
|
-
|---------|-------------|
|
|
837
|
-
| `securenow blocklist` | List all blocked IPs |
|
|
838
|
-
| `securenow blocklist add <ip>` | Block an IP address |
|
|
839
|
-
| `securenow blocklist add <cidr> --reason "brute force"` | Block a CIDR range with reason |
|
|
840
|
-
| `securenow blocklist remove <id>` | Unblock an IP |
|
|
841
|
-
| `securenow blocklist stats` | Blocklist statistics |
|
|
842
|
-
| `securenow trusted` | List trusted IPs |
|
|
843
|
-
| `securenow trusted add <ip> --label "office"` | Add a trusted IP |
|
|
844
|
-
| `securenow trusted remove <id>` | Remove a trusted IP |
|
|
845
|
-
|
|
846
|
-
### Settings & Config
|
|
847
|
-
|
|
848
|
-
| Command | What It Does |
|
|
849
|
-
|---------|-------------|
|
|
850
|
-
| `securenow config set <key> <value>` | Set a config value |
|
|
851
|
-
| `securenow config get [key]` | Get a config value (or show all) |
|
|
852
|
-
| `securenow config path` | Show config + credentials file paths |
|
|
853
|
-
| `securenow instances` | List ClickHouse instances |
|
|
854
|
-
| `securenow instances test <id>` | Test an instance connection |
|
|
855
|
-
| `securenow version` | Show CLI version |
|
|
856
|
-
|
|
857
|
-
### Global Flags
|
|
858
|
-
|
|
859
|
-
Every command supports:
|
|
860
|
-
|
|
861
|
-
| Flag | Effect |
|
|
862
|
-
|------|--------|
|
|
863
|
-
| `--json` | Output raw JSON (pipe to `jq`, scripts, etc.) |
|
|
864
|
-
| `--help` | Show help for any command |
|
|
865
|
-
| `--app <key>` | Override the default app for this command |
|
|
866
|
-
|
|
867
|
-
---
|
|
868
|
-
|
|
869
|
-
## Step 6 — Forensics Chat — Ask Questions in Plain English
|
|
870
|
-
|
|
871
|
-
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.
|
|
872
|
-
|
|
873
|
-
### How to Use
|
|
874
|
-
|
|
875
|
-
```bash
|
|
876
|
-
npx securenow forensics "your question here"
|
|
877
|
-
```
|
|
878
|
-
|
|
879
|
-
### Example Queries
|
|
880
|
-
|
|
881
|
-
**Find suspicious activity:**
|
|
882
|
-
|
|
883
|
-
```bash
|
|
884
|
-
npx securenow forensics "show me all 401 responses in the last hour"
|
|
885
|
-
```
|
|
886
|
-
|
|
887
|
-
**Hunt for attackers:**
|
|
888
|
-
|
|
889
|
-
```bash
|
|
890
|
-
npx securenow forensics "which IPs sent the most requests in the last 24 hours"
|
|
891
|
-
```
|
|
892
|
-
|
|
893
|
-
**Find slow endpoints:**
|
|
894
|
-
|
|
895
|
-
```bash
|
|
896
|
-
npx securenow forensics "show the slowest API endpoints this week"
|
|
897
|
-
```
|
|
898
|
-
|
|
899
|
-
**Investigate a specific IP:**
|
|
900
|
-
|
|
901
|
-
```bash
|
|
902
|
-
npx securenow forensics "show all requests from 185.220.101.1 in the last 7 days"
|
|
903
|
-
```
|
|
904
|
-
|
|
905
|
-
**Error analysis:**
|
|
906
|
-
|
|
907
|
-
```bash
|
|
908
|
-
npx securenow forensics "count 500 errors per endpoint in the last 24 hours"
|
|
909
|
-
```
|
|
910
|
-
|
|
911
|
-
**Brute force detection:**
|
|
912
|
-
|
|
913
|
-
```bash
|
|
914
|
-
npx securenow forensics "find IPs that sent more than 100 POST requests to /login today"
|
|
915
|
-
```
|
|
916
|
-
|
|
917
|
-
**Data exfiltration patterns:**
|
|
918
|
-
|
|
919
|
-
```bash
|
|
920
|
-
npx securenow forensics "show requests with response bodies larger than 1MB"
|
|
921
|
-
```
|
|
922
|
-
|
|
923
|
-
### How It Works
|
|
924
|
-
|
|
925
|
-
1. You type a question in English
|
|
926
|
-
2. SecureNow's AI converts it to a SQL query
|
|
927
|
-
3. The query runs against your ClickHouse traces database
|
|
928
|
-
4. Results are displayed as a table in your terminal
|
|
929
|
-
|
|
930
|
-
The CLI shows you both the generated SQL and the results:
|
|
931
|
-
|
|
932
|
-
```
|
|
933
|
-
Generated SQL
|
|
934
|
-
|
|
935
|
-
SELECT ClientIP, count() as cnt FROM traces
|
|
936
|
-
WHERE Timestamp > now() - INTERVAL 1 HOUR AND ResponseStatusCode = 401
|
|
937
|
-
GROUP BY ClientIP ORDER BY cnt DESC LIMIT 20
|
|
938
|
-
|
|
939
|
-
Results (5 rows)
|
|
940
|
-
|
|
941
|
-
ClientIP cnt
|
|
942
|
-
185.220.101.1 342
|
|
943
|
-
45.134.26.8 128
|
|
944
|
-
...
|
|
945
|
-
```
|
|
946
|
-
|
|
947
|
-
### Save & Reuse Queries
|
|
948
|
-
|
|
949
|
-
View your saved query library:
|
|
950
|
-
|
|
951
|
-
```bash
|
|
952
|
-
npx securenow forensics library
|
|
953
|
-
```
|
|
954
|
-
|
|
955
|
-
### Output as JSON
|
|
956
|
-
|
|
957
|
-
Pipe forensic results to scripts or other tools:
|
|
958
|
-
|
|
959
|
-
```bash
|
|
960
|
-
npx securenow forensics "top 10 IPs by request count today" --json | jq '.result'
|
|
961
|
-
```
|
|
962
|
-
|
|
963
|
-
---
|
|
964
|
-
|
|
965
|
-
## Step 7 — Block & Manage IPs
|
|
966
|
-
|
|
967
|
-
SecureNow gives you full IP lifecycle management — investigate, block, trust, and audit.
|
|
968
|
-
|
|
969
|
-
### Investigate an IP
|
|
970
|
-
|
|
971
|
-
Before blocking, look up the IP's intelligence:
|
|
972
|
-
|
|
973
|
-
```bash
|
|
974
|
-
npx securenow ip 185.220.101.1
|
|
975
|
-
```
|
|
976
|
-
|
|
977
|
-
Output:
|
|
978
|
-
|
|
979
|
-
```
|
|
980
|
-
IP Intelligence: 185.220.101.1
|
|
981
|
-
|
|
982
|
-
Country Germany (DE)
|
|
983
|
-
ISP Tor Exit Node
|
|
984
|
-
Usage Type Hosting
|
|
985
|
-
Abuse Score 100/100
|
|
986
|
-
Malicious Yes
|
|
987
|
-
Bot Yes
|
|
988
|
-
Total Reports 4,521
|
|
989
|
-
|
|
990
|
-
Risk Factors
|
|
991
|
-
• Known Tor exit node
|
|
992
|
-
• High abuse confidence score
|
|
993
|
-
• Associated with brute force attacks
|
|
994
|
-
|
|
995
|
-
Attack Types
|
|
996
|
-
• SSH Brute Force
|
|
997
|
-
• Web Application Attack
|
|
998
|
-
• Port Scanning
|
|
999
|
-
```
|
|
1000
|
-
|
|
1001
|
-
### See What That IP Did
|
|
1002
|
-
|
|
1003
|
-
```bash
|
|
1004
|
-
npx securenow ip traces 185.220.101.1
|
|
1005
|
-
```
|
|
1006
|
-
|
|
1007
|
-
Shows all traced requests from that IP — method, status code, URL, duration, and time.
|
|
1008
|
-
|
|
1009
|
-
### Block an IP
|
|
1010
|
-
|
|
1011
|
-
```bash
|
|
1012
|
-
npx securenow blocklist add 185.220.101.1 --reason "tor exit node, brute force"
|
|
1013
|
-
```
|
|
1014
|
-
|
|
1015
|
-
Block a CIDR range:
|
|
1016
|
-
|
|
1017
|
-
```bash
|
|
1018
|
-
npx securenow blocklist add 185.220.101.0/24 --reason "malicious subnet"
|
|
1019
|
-
```
|
|
1020
|
-
|
|
1021
|
-
Block with an expiration:
|
|
1022
|
-
|
|
1023
|
-
```bash
|
|
1024
|
-
npx securenow blocklist add 45.134.26.8 --reason "rate limiting" --duration 24h
|
|
1025
|
-
```
|
|
1026
|
-
|
|
1027
|
-
### View All Blocked IPs
|
|
1028
|
-
|
|
1029
|
-
```bash
|
|
1030
|
-
npx securenow blocklist
|
|
1031
|
-
```
|
|
1032
|
-
|
|
1033
|
-
Output:
|
|
1034
|
-
|
|
1035
|
-
```
|
|
1036
|
-
ID IP/CIDR Reason Source Added Expires
|
|
1037
|
-
abc123... 185.220.101.1 tor exit node manual 2 hours ago permanent
|
|
1038
|
-
def456... 185.220.101.0/24 malicious subnet manual 1 hour ago permanent
|
|
1039
|
-
ghi789... 45.134.26.8 rate limiting manual 30 min ago 2024-01-16
|
|
1040
|
-
```
|
|
1041
|
-
|
|
1042
|
-
### Unblock an IP
|
|
1043
|
-
|
|
1044
|
-
```bash
|
|
1045
|
-
npx securenow blocklist remove abc123
|
|
1046
|
-
```
|
|
1047
|
-
|
|
1048
|
-
### Blocklist Statistics
|
|
1049
|
-
|
|
1050
|
-
```bash
|
|
1051
|
-
npx securenow blocklist stats
|
|
1052
|
-
```
|
|
1053
|
-
|
|
1054
|
-
Shows total active blocks, removed blocks, manual vs automated counts, and active automation rules.
|
|
1055
|
-
|
|
1056
|
-
### Trust an IP (Whitelist)
|
|
1057
|
-
|
|
1058
|
-
Trusted IPs bypass security detections:
|
|
1059
|
-
|
|
1060
|
-
```bash
|
|
1061
|
-
npx securenow trusted add 203.0.113.50 --label "office VPN"
|
|
1062
|
-
```
|
|
1063
|
-
|
|
1064
|
-
List trusted IPs:
|
|
1065
|
-
|
|
1066
|
-
```bash
|
|
1067
|
-
npx securenow trusted
|
|
1068
|
-
```
|
|
1069
|
-
|
|
1070
|
-
Remove a trusted IP:
|
|
1071
|
-
|
|
1072
|
-
```bash
|
|
1073
|
-
npx securenow trusted remove <id>
|
|
1074
|
-
```
|
|
1075
|
-
|
|
1076
|
-
### Full Investigation → Block Workflow
|
|
1077
|
-
|
|
1078
|
-
Here is the typical workflow for handling a suspicious IP:
|
|
1079
|
-
|
|
1080
|
-
```bash
|
|
1081
|
-
# 1. Check forensics for anomalies
|
|
1082
|
-
npx securenow forensics "IPs with more than 50 failed login attempts today"
|
|
1083
|
-
|
|
1084
|
-
# 2. Pick a suspicious IP and investigate
|
|
1085
|
-
npx securenow ip 185.220.101.1
|
|
1086
|
-
|
|
1087
|
-
# 3. See exactly what it did
|
|
1088
|
-
npx securenow ip traces 185.220.101.1
|
|
1089
|
-
|
|
1090
|
-
# 4. Block it
|
|
1091
|
-
npx securenow blocklist add 185.220.101.1 --reason "brute force login attempts"
|
|
1092
|
-
|
|
1093
|
-
# 5. Verify it's blocked
|
|
1094
|
-
npx securenow blocklist
|
|
1095
|
-
```
|
|
1096
|
-
|
|
1097
|
-
### Enforce the Blocklist on Your App (Firewall)
|
|
1098
|
-
|
|
1099
|
-
Once you've built a blocklist, enforce it at your application layer — automatically, with zero code changes:
|
|
1100
|
-
|
|
1101
|
-
```bash
|
|
1102
|
-
# Add your API key to .env
|
|
1103
|
-
SECURENOW_API_KEY=snk_live_abc123...
|
|
1104
|
-
```
|
|
1105
|
-
|
|
1106
|
-
Restart your app. The firewall syncs the blocklist every 60 seconds and blocks matching IPs with a 403 response:
|
|
1107
|
-
|
|
1108
|
-
```
|
|
1109
|
-
[securenow] Firewall: ENABLED
|
|
1110
|
-
[securenow] Firewall: Layer 1 (HTTP 403) active
|
|
1111
|
-
[securenow] Firewall: synced 142 blocked IPs
|
|
1112
|
-
```
|
|
1113
|
-
|
|
1114
|
-
Enable additional layers for defense in depth:
|
|
1115
|
-
|
|
1116
|
-
```bash
|
|
1117
|
-
# TCP-level blocking (zero bytes sent back)
|
|
1118
|
-
SECURENOW_FIREWALL_TCP=1
|
|
1119
|
-
|
|
1120
|
-
# OS-level blocking (iptables/nftables, Linux only)
|
|
1121
|
-
SECURENOW_FIREWALL_IPTABLES=1
|
|
1122
|
-
|
|
1123
|
-
# Cloud WAF blocking (Cloudflare, AWS WAF, GCP Cloud Armor)
|
|
1124
|
-
SECURENOW_FIREWALL_CLOUD=cloudflare
|
|
1125
|
-
```
|
|
1126
|
-
|
|
1127
|
-
Check firewall status:
|
|
1128
|
-
|
|
1129
|
-
```bash
|
|
1130
|
-
npx securenow firewall status
|
|
1131
|
-
npx securenow firewall test-ip 185.220.101.1
|
|
1132
|
-
```
|
|
1133
|
-
|
|
1134
|
-
See the [Firewall Guide](FIREWALL-GUIDE.md) for the full reference.
|
|
1135
|
-
|
|
1136
|
-
---
|
|
1137
|
-
|
|
1138
|
-
## Step 8 — Monitor, Detect & Respond
|
|
1139
|
-
|
|
1140
|
-
### Daily Monitoring
|
|
1141
|
-
|
|
1142
|
-
```bash
|
|
1143
|
-
# Quick overview of all your apps
|
|
1144
|
-
npx securenow status
|
|
1145
|
-
|
|
1146
|
-
# Check for unread alerts
|
|
1147
|
-
npx securenow notifications unread
|
|
1148
|
-
|
|
1149
|
-
# List open security issues
|
|
1150
|
-
npx securenow issues --status open
|
|
1151
|
-
```
|
|
1152
|
-
|
|
1153
|
-
### Respond to an Issue
|
|
1154
|
-
|
|
1155
|
-
```bash
|
|
1156
|
-
# Read the full issue detail (includes AI analysis)
|
|
1157
|
-
npx securenow issues show <id>
|
|
1158
|
-
|
|
1159
|
-
# If it's resolved, mark it
|
|
1160
|
-
npx securenow issues resolve <id>
|
|
1161
|
-
```
|
|
1162
|
-
|
|
1163
|
-
### AI Trace Analysis
|
|
1164
|
-
|
|
1165
|
-
Let SecureNow's AI analyze a suspicious trace for security issues:
|
|
1166
|
-
|
|
1167
|
-
```bash
|
|
1168
|
-
npx securenow traces analyze <traceId>
|
|
1169
|
-
```
|
|
1170
|
-
|
|
1171
|
-
Returns a summary, risk level, specific security issues found, and recommended actions.
|
|
1172
|
-
|
|
1173
|
-
### Set Up Alerts
|
|
1174
|
-
|
|
1175
|
-
Configure alert rules and channels from the [dashboard](https://app.securenow.ai/dashboard), then monitor from the CLI:
|
|
1176
|
-
|
|
1177
|
-
```bash
|
|
1178
|
-
# List your alert rules
|
|
1179
|
-
npx securenow alerts rules
|
|
1180
|
-
|
|
1181
|
-
# Show one rule / set application scope (all apps vs explicit keys)
|
|
1182
|
-
npx securenow alerts rules show <rule-id>
|
|
1183
|
-
npx securenow alerts rules update <rule-id> --applications-all
|
|
1184
|
-
npx securenow alerts rules update <rule-id> --apps key1,key2
|
|
1185
|
-
|
|
1186
|
-
# List alert channels (email, Slack, webhook)
|
|
1187
|
-
npx securenow alerts channels
|
|
1188
|
-
|
|
1189
|
-
# View alert history
|
|
1190
|
-
npx securenow alerts history --limit 20
|
|
1191
|
-
```
|
|
1192
|
-
|
|
1193
|
-
---
|
|
1194
|
-
|
|
1195
|
-
## Deployment
|
|
1196
|
-
|
|
1197
|
-
### PM2 Setup (All Frameworks)
|
|
1198
|
-
|
|
1199
|
-
```javascript
|
|
1200
|
-
// ecosystem.config.cjs
|
|
1201
|
-
module.exports = {
|
|
1202
|
-
apps: [{
|
|
1203
|
-
name: 'my-app',
|
|
1204
|
-
script: './app.js',
|
|
1205
|
-
node_args: '-r securenow/register',
|
|
1206
|
-
env: {
|
|
1207
|
-
SECURENOW_APPID: 'my-app',
|
|
1208
|
-
SECURENOW_INSTANCE: 'https://freetrial.securenow.ai:4318',
|
|
1209
|
-
SECURENOW_LOGGING_ENABLED: '1',
|
|
1210
|
-
SECURENOW_NO_UUID: '1',
|
|
1211
|
-
SECURENOW_CAPTURE_BODY: '1',
|
|
1212
|
-
PORT: 3000,
|
|
1213
|
-
}
|
|
1214
|
-
}]
|
|
1215
|
-
};
|
|
1216
|
-
```
|
|
1217
|
-
|
|
1218
|
-
```bash
|
|
1219
|
-
pm2 start ecosystem.config.cjs
|
|
1220
|
-
```
|
|
1221
|
-
|
|
1222
|
-
**NestJS (TypeScript):**
|
|
1223
|
-
|
|
1224
|
-
```javascript
|
|
1225
|
-
{
|
|
1226
|
-
name: 'my-nestjs-app',
|
|
1227
|
-
script: 'dist/main.js',
|
|
1228
|
-
node_args: '-r ./instrument.js',
|
|
1229
|
-
env: { /* same as above */ }
|
|
1230
|
-
}
|
|
1231
|
-
```
|
|
1232
|
-
|
|
1233
|
-
**Hono (ESM `.mjs`):**
|
|
1234
|
-
|
|
1235
|
-
```javascript
|
|
1236
|
-
{
|
|
1237
|
-
name: 'my-hono-app',
|
|
1238
|
-
script: 'app.mjs',
|
|
1239
|
-
node_args: '-r securenow/register',
|
|
1240
|
-
env: {
|
|
1241
|
-
SECURENOW_CAPTURE_BODY: '0', // Required for Hono
|
|
1242
|
-
/* ... other vars ... */
|
|
1243
|
-
}
|
|
1244
|
-
}
|
|
1245
|
-
```
|
|
1246
|
-
|
|
1247
|
-
### Docker
|
|
1248
|
-
|
|
1249
|
-
```dockerfile
|
|
1250
|
-
FROM node:20-alpine
|
|
1251
|
-
WORKDIR /app
|
|
1252
|
-
COPY package*.json ./
|
|
1253
|
-
RUN npm install
|
|
1254
|
-
COPY . .
|
|
1255
|
-
|
|
1256
|
-
ENV SECURENOW_APPID=my-app
|
|
1257
|
-
ENV SECURENOW_INSTANCE=https://collector:4318
|
|
1258
|
-
ENV SECURENOW_LOGGING_ENABLED=1
|
|
1259
|
-
ENV SECURENOW_NO_UUID=1
|
|
1260
|
-
|
|
1261
|
-
EXPOSE 3000
|
|
1262
|
-
CMD ["node", "-r", "securenow/register", "app.js"]
|
|
1263
|
-
```
|
|
1264
|
-
|
|
1265
|
-
---
|
|
1266
|
-
|
|
1267
|
-
## Compatibility Matrix
|
|
1268
|
-
|
|
1269
|
-
| Framework | Traces | Logs | Body Capture | Init Method | Notes |
|
|
1270
|
-
|-----------|--------|------|--------------|-------------|-------|
|
|
1271
|
-
| Express | Yes | Yes | Yes | `require()` or `-r` | Fully compatible |
|
|
1272
|
-
| Fastify | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
|
|
1273
|
-
| Koa | Yes | Yes | Yes | `require()` or `-r` | Needs `koa-bodyparser` |
|
|
1274
|
-
| NestJS | Yes | Yes | Yes | `instrument.js` + `-r ./instrument.js` | Create `instrument.js` with `require('securenow/register')` |
|
|
1275
|
-
| Hapi | Yes | Yes | **No** | `require()` or `-r` | Set `SECURENOW_CAPTURE_BODY=0` |
|
|
1276
|
-
| h3 | Yes | Yes | Yes | `require()` or `-r` | Uses `toNodeListener()` |
|
|
1277
|
-
| Polka | Yes | Yes | Yes | `require()` or `-r` | Needs manual body parser |
|
|
1278
|
-
| Micro/HTTP | Yes | Yes | Yes | `require()` or `-r` | Raw `http.createServer` |
|
|
1279
|
-
| Hono | Yes | Yes | **No** | `-r` flag only (ESM) | Set `SECURENOW_CAPTURE_BODY=0` |
|
|
1280
|
-
| Feathers | Yes | Yes | Yes | `require()` or `-r` | Express transport |
|
|
1281
|
-
| Next.js | Yes | Yes | Yes | `instrumentation.ts` | Use `securenow init` |
|
|
1282
|
-
|
|
1283
|
-
---
|
|
1284
|
-
|
|
1285
|
-
## Troubleshooting
|
|
1286
|
-
|
|
1287
|
-
### Traces not appearing
|
|
1288
|
-
|
|
1289
|
-
1. Verify `SECURENOW_APPID` and `SECURENOW_INSTANCE` are set
|
|
1290
|
-
2. Set `SECURENOW_NO_UUID=1` so the dashboard matches your app key exactly
|
|
1291
|
-
3. Enable debug logging: `OTEL_LOG_LEVEL=debug node -r securenow/register app.js`
|
|
1292
|
-
|
|
1293
|
-
### Logs not appearing
|
|
1294
|
-
|
|
1295
|
-
1. Confirm `SECURENOW_LOGGING_ENABLED=1` is set
|
|
1296
|
-
2. Check that startup output shows `📋 Logging: ENABLED`
|
|
1297
|
-
3. Any `console.log` / `console.error` in your app automatically becomes an OTLP log record
|
|
1298
|
-
|
|
1299
|
-
### ESM apps (.mjs / "type": "module")
|
|
1300
|
-
|
|
1301
|
-
Use `NODE_OPTIONS="-r securenow/register"` or `node -r securenow/register app.mjs`.
|
|
1302
|
-
Do **not** add `require('securenow/register')` inside `.mjs` files.
|
|
1303
|
-
|
|
1304
|
-
### Body capture crashes / empty payloads
|
|
1305
|
-
|
|
1306
|
-
Set `SECURENOW_CAPTURE_BODY=0` for Fastify, Hapi, and Hono. These frameworks use custom stream handling that conflicts with the body capture hook.
|
|
1307
|
-
|
|
1308
|
-
### CLI says "Not logged in"
|
|
1309
|
-
|
|
1310
|
-
```bash
|
|
1311
|
-
npx securenow login
|
|
1312
|
-
```
|
|
1313
|
-
|
|
1314
|
-
Or re-authenticate with a token:
|
|
1315
|
-
|
|
1316
|
-
```bash
|
|
1317
|
-
npx securenow login --token <YOUR_TOKEN>
|
|
1318
|
-
```
|
|
1319
|
-
|
|
1320
|
-
Or set the env var directly:
|
|
1321
|
-
|
|
1322
|
-
```bash
|
|
1323
|
-
SECURENOW_TOKEN=<YOUR_JWT> npx securenow whoami
|
|
1324
|
-
```
|
|
1325
|
-
|
|
1326
|
-
### CLI says "Session expired"
|
|
1327
|
-
|
|
1328
|
-
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.
|
|
1329
|
-
|
|
1330
|
-
---
|
|
1331
|
-
|
|
1332
|
-
## Complete Documentation
|
|
1333
|
-
|
|
1334
|
-
- [Express Guide](./EXPRESS-SETUP-GUIDE.md)
|
|
1335
|
-
- [Next.js Guide](./NEXTJS-SETUP-COMPLETE.md)
|
|
1336
|
-
- [Logging Guide](./LOGGING-GUIDE.md)
|
|
1337
|
-
- [Environment Variables](./ENVIRONMENT-VARIABLES.md)
|
|
1338
|
-
- [Body Capture](./REQUEST-BODY-CAPTURE.md)
|
|
1339
|
-
- [NPM README](../NPM_README.md)
|
|
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!** 🚀
|