securenow 7.6.6 → 7.6.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/NPM_README.md +13 -13
  2. package/README.md +21 -37
  3. package/app-config.js +5 -3
  4. package/cli/config.js +4 -3
  5. package/cli/diagnostics.js +54 -15
  6. package/cli/run.js +40 -11
  7. package/firewall-only.js +1 -1
  8. package/firewall.js +88 -57
  9. package/mcp/catalog.js +1 -1
  10. package/nextjs-webpack-config.js +3 -15
  11. package/nextjs.js +21 -23
  12. package/nuxt-server-plugin.mjs +20 -10
  13. package/package.json +33 -34
  14. package/register.js +1 -1
  15. package/tracing.js +17 -7
  16. package/web-vite.mjs +23 -13
  17. package/CONSUMING-APPS-GUIDE.md +0 -463
  18. package/docs/ALL-FRAMEWORKS-QUICKSTART.md +0 -1388
  19. package/docs/API-KEYS-GUIDE.md +0 -278
  20. package/docs/ARCHITECTURE.md +0 -408
  21. package/docs/AUTO-BODY-CAPTURE.md +0 -412
  22. package/docs/AUTO-SETUP-SUMMARY.md +0 -331
  23. package/docs/AUTO-SETUP.md +0 -419
  24. package/docs/AUTOMATIC-IP-CAPTURE.md +0 -359
  25. package/docs/BODY-CAPTURE-FIX.md +0 -261
  26. package/docs/BODY-CAPTURE-QUICKSTART.md +0 -147
  27. package/docs/CHANGELOG-NEXTJS.md +0 -235
  28. package/docs/COMPLETION-REPORT.md +0 -408
  29. package/docs/CUSTOMER-GUIDE.md +0 -364
  30. package/docs/EASIEST-SETUP.md +0 -342
  31. package/docs/ENVIRONMENT-VARIABLES.md +0 -166
  32. package/docs/ENVIRONMENTS.md +0 -60
  33. package/docs/EXPRESS-BODY-CAPTURE.md +0 -1028
  34. package/docs/EXPRESS-SETUP-GUIDE.md +0 -722
  35. package/docs/FINAL-SOLUTION.md +0 -335
  36. package/docs/FIREWALL-GUIDE.md +0 -440
  37. package/docs/IMPLEMENTATION-SUMMARY.md +0 -410
  38. package/docs/INDEX.md +0 -222
  39. package/docs/LOGGING-GUIDE.md +0 -704
  40. package/docs/LOGGING-QUICKSTART.md +0 -221
  41. package/docs/MCP-GUIDE.md +0 -58
  42. package/docs/NEXTJS-BODY-CAPTURE-COMPARISON.md +0 -323
  43. package/docs/NEXTJS-BODY-CAPTURE.md +0 -368
  44. package/docs/NEXTJS-GUIDE.md +0 -392
  45. package/docs/NEXTJS-QUICKSTART.md +0 -83
  46. package/docs/NEXTJS-SETUP-COMPLETE.md +0 -795
  47. package/docs/NEXTJS-WEBPACK-WARNINGS.md +0 -267
  48. package/docs/NEXTJS-WRAPPER-APPROACH.md +0 -414
  49. package/docs/NUXT-GUIDE.md +0 -173
  50. package/docs/QUICKSTART-BODY-CAPTURE.md +0 -293
  51. package/docs/REDACTION-EXAMPLES.md +0 -484
  52. package/docs/REQUEST-BODY-CAPTURE.md +0 -587
  53. package/docs/SOLUTION-SUMMARY.md +0 -312
  54. package/docs/VERCEL-OTEL-MIGRATION.md +0 -255
  55. package/examples/README.md +0 -265
  56. package/examples/express-with-logging.js +0 -137
  57. package/examples/instrumentation-with-auto-capture.ts +0 -41
  58. package/examples/next.config.js +0 -37
  59. package/examples/nextjs-api-route-with-body-capture.ts +0 -54
  60. package/examples/nextjs-env-example.txt +0 -32
  61. package/examples/nextjs-instrumentation.js +0 -36
  62. package/examples/nextjs-instrumentation.ts +0 -36
  63. package/examples/nextjs-middleware.js +0 -37
  64. package/examples/nextjs-middleware.ts +0 -37
  65. package/examples/nextjs-with-logging-example.md +0 -301
  66. package/examples/nextjs-with-options.ts +0 -36
  67. package/examples/test-nextjs-setup.js +0 -70
  68. package/postinstall.js +0 -296
@@ -1,1028 +0,0 @@
1
- # Request Body Capture for Express.js with PM2
2
-
3
- This guide shows how to automatically capture request bodies in Express.js applications, including those running with PM2 clustering.
4
-
5
- **Available for both JavaScript and TypeScript projects!**
6
-
7
- ## 📖 Table of Contents
8
-
9
- - [Overview](#-overview)
10
- - [Quick Start](#-quick-start)
11
- - [How It Works](#-how-it-works)
12
- - [Configuration](#-configuration)
13
- - [PM2 Clustering](#-pm2-clustering)
14
- - [Supported Content Types](#-supported-content-types)
15
- - [Complete Example (JS & TS)](#-example-complete-express--pm2-setup)
16
- - [Testing Body Capture](#-testing-body-capture)
17
- - [Troubleshooting](#-troubleshooting)
18
- - [Security Considerations](#-security-considerations)
19
- - [Performance Impact](#-performance-impact)
20
- - [TypeScript-Specific Guide](#-typescript-specific-guide)
21
- - [Advanced Topics](#-advanced-topics)
22
-
23
- ---
24
-
25
- ## 🎯 Overview
26
-
27
- **SecureNow** captures request bodies at the HTTP instrumentation level, **before Express parses them**. This works automatically for most Express apps, but you need to understand how it interacts with Express body parsers.
28
-
29
- This guide provides examples for both **JavaScript** and **TypeScript** projects.
30
-
31
- ### JavaScript vs TypeScript
32
-
33
- | Feature | JavaScript | TypeScript |
34
- |---------|-----------|------------|
35
- | **Setup Complexity** | ⚡ Simple | 🔧 Moderate |
36
- | **Type Safety** | ❌ No | ✅ Yes |
37
- | **Build Step** | ❌ Not required | ✅ Required |
38
- | **SecureNow Setup** | Identical | Identical |
39
- | **Body Capture** | ✅ Works | ✅ Works |
40
- | **Production Ready** | ✅ Yes | ✅ Yes |
41
-
42
- **Both work identically with SecureNow!** Choose based on your project preference.
43
-
44
- ## ⚡ Quick Start
45
-
46
- ### 1. Install SecureNow
47
-
48
- ```bash
49
- npm install securenow
50
- ```
51
-
52
- ### 2. Configure Environment Variables
53
-
54
- Create `.env` or set in PM2 ecosystem file:
55
-
56
- ```bash
57
- SECURENOW_APPID=my-express-api
58
- SECURENOW_INSTANCE=http://your-otlp-backend:4318
59
- SECURENOW_CAPTURE_BODY=1
60
- SECURENOW_MAX_BODY_SIZE=10240
61
- ```
62
-
63
- ### 3. Enable in Express App
64
-
65
- **Option A: Using `--require` flag (Recommended for PM2)**
66
-
67
- **JavaScript:**
68
-
69
- ```javascript
70
- // app.js - NO changes needed to your code!
71
- const express = require('express');
72
- const app = express();
73
-
74
- app.use(express.json());
75
-
76
- app.post('/api/login', (req, res) => {
77
- // Your existing code - body is automatically captured
78
- res.json({ success: true });
79
- });
80
-
81
- app.listen(3000);
82
- ```
83
-
84
- **TypeScript:**
85
-
86
- ```typescript
87
- // app.ts - NO changes needed to your code!
88
- import express, { Request, Response } from 'express';
89
- const app = express();
90
-
91
- app.use(express.json());
92
-
93
- app.post('/api/login', (req: Request, res: Response) => {
94
- // Your existing code - body is automatically captured
95
- res.json({ success: true });
96
- });
97
-
98
- app.listen(3000);
99
- ```
100
-
101
- **Start with PM2:**
102
-
103
- ```bash
104
- # JavaScript
105
- pm2 start app.js --node-args="-r securenow/register"
106
-
107
- # TypeScript (after compiling)
108
- npm run build
109
- pm2 start dist/app.js --node-args="-r securenow/register"
110
- ```
111
-
112
- **Or in `ecosystem.config.js`:**
113
-
114
- ```javascript
115
- module.exports = {
116
- apps: [{
117
- name: 'express-api',
118
- script: './app.js', // or './dist/app.js' for TypeScript
119
- instances: 4,
120
- exec_mode: 'cluster',
121
- node_args: '-r securenow/register',
122
- env: {
123
- NODE_ENV: 'production',
124
- SECURENOW_APPID: 'express-api',
125
- SECURENOW_CAPTURE_BODY: '1',
126
- SECURENOW_NO_UUID: '1', // Same service.name across workers
127
- }
128
- }]
129
- };
130
- ```
131
-
132
- **Option B: Require in Code**
133
-
134
- **JavaScript:**
135
-
136
- ```javascript
137
- // app.js - Add this at the VERY TOP
138
- require('securenow/register');
139
-
140
- const express = require('express');
141
- // ... rest of your app
142
- ```
143
-
144
- **TypeScript:**
145
-
146
- ```typescript
147
- // app.ts - Add this at the VERY TOP
148
- import 'securenow/register';
149
-
150
- import express from 'express';
151
- // ... rest of your app
152
- ```
153
-
154
- ## 📝 How It Works
155
-
156
- ### Body Capture Flow
157
-
158
- ```
159
- ┌─────────────────────────────────────────────────────────┐
160
- │ 1. HTTP Request arrives │
161
- │ ↓ │
162
- │ 2. SecureNow HTTP Instrumentation reads raw stream │
163
- │ - Buffers body chunks │
164
- │ - Does NOT consume stream │
165
- │ ↓ │
166
- │ 3. Express body-parser reads stream │
167
- │ - Parses JSON/form data │
168
- │ - Populates req.body │
169
- │ ↓ │
170
- │ 4. SecureNow captures body on 'end' event │
171
- │ - Redacts sensitive fields │
172
- │ - Attaches to OpenTelemetry span │
173
- │ ↓ │
174
- │ 5. Your Express handler runs │
175
- │ - req.body is available as normal │
176
- └─────────────────────────────────────────────────────────┘
177
- ```
178
-
179
- ### Key Points
180
-
181
- 1. **Stream Buffering**: SecureNow listens to the Node.js HTTP request stream and buffers chunks as they arrive
182
- 2. **Non-Destructive**: The buffering doesn't consume the stream, so Express can still read it
183
- 3. **Automatic Redaction**: Sensitive fields (passwords, tokens, etc.) are automatically redacted
184
- 4. **Size Limiting**: Bodies larger than `SECURENOW_MAX_BODY_SIZE` are not captured
185
-
186
- ## 🔧 Configuration
187
-
188
- ### Environment Variables
189
-
190
- | Variable | Description | Default |
191
- |----------|-------------|---------|
192
- | `SECURENOW_CAPTURE_BODY` | Enable body capture (`1` or `true`) | `0` (disabled) |
193
- | `SECURENOW_MAX_BODY_SIZE` | Max body size in bytes | `10240` (10KB) |
194
- | `SECURENOW_SENSITIVE_FIELDS` | Comma-separated additional sensitive fields | (see below) |
195
- | `SECURENOW_CAPTURE_MULTIPART` | Enable multipart/form-data streaming capture (`1` or `true`) | `0` (disabled) |
196
-
197
- ### Default Sensitive Fields
198
-
199
- These fields are **automatically redacted**:
200
-
201
- ```javascript
202
- 'password', 'passwd', 'pwd', 'secret', 'token', 'api_key', 'apikey',
203
- 'access_token', 'auth', 'credentials', 'mysql_pwd', 'stripeToken',
204
- 'card', 'cardnumber', 'ccv', 'cvc', 'cvv', 'ssn', 'pin'
205
- ```
206
-
207
- ### Adding Custom Sensitive Fields
208
-
209
- ```bash
210
- # In .env or PM2 config
211
- SECURENOW_SENSITIVE_FIELDS=custom_token,internal_key,private_data
212
- ```
213
-
214
- ## 🚀 PM2 Clustering
215
-
216
- ### Cluster Mode Setup
217
-
218
- **ecosystem.config.js:**
219
-
220
- ```javascript
221
- module.exports = {
222
- apps: [{
223
- name: 'express-api',
224
- script: './server.js',
225
- instances: 'max', // Use all CPU cores
226
- exec_mode: 'cluster',
227
- node_args: '-r securenow/register',
228
- env: {
229
- NODE_ENV: 'production',
230
- SECURENOW_APPID: 'express-api',
231
- SECURENOW_INSTANCE: 'http://otel-collector:4318',
232
- SECURENOW_CAPTURE_BODY: '1',
233
- SECURENOW_NO_UUID: '1', // Same service.name
234
- SECURENOW_STRICT: '1', // Fail if APPID missing
235
- }
236
- }]
237
- };
238
- ```
239
-
240
- **Start cluster:**
241
-
242
- ```bash
243
- pm2 start ecosystem.config.js
244
- ```
245
-
246
- ### Service Naming in Clusters
247
-
248
- **Without `SECURENOW_NO_UUID=1`:**
249
- - Each worker gets unique service name: `express-api-abc123`, `express-api-def456`
250
- - Good for debugging individual workers
251
- - Traces are separated per worker
252
-
253
- **With `SECURENOW_NO_UUID=1`:**
254
- - All workers share same service name: `express-api`
255
- - Traces are grouped together
256
- - Recommended for production
257
-
258
- ### Monitoring Workers
259
-
260
- ```bash
261
- # View all workers
262
- pm2 list
263
-
264
- # View logs (all workers)
265
- pm2 logs express-api
266
-
267
- # View logs for specific worker
268
- pm2 logs express-api --lines 100
269
- ```
270
-
271
- ## 📋 Supported Content Types
272
-
273
- | Content Type | Captured? | Parsed? | Redacted? |
274
- |--------------|-----------|---------|-----------|
275
- | `application/json` | ✅ Yes | ✅ Yes | ✅ Yes |
276
- | `application/graphql` | ✅ Yes | ✅ Yes | ✅ Yes |
277
- | `application/x-www-form-urlencoded` | ✅ Yes | ✅ Yes | ✅ Yes |
278
- | `multipart/form-data` | ✅ Metadata | ✅ Streaming | ✅ Yes |
279
- | `text/plain` | ❌ No | N/A | N/A |
280
-
281
- **Note**: Multipart capture requires `SECURENOW_CAPTURE_MULTIPART=1` (v5.8.0+). Uses a streaming parser — text field values and file metadata (name, filename, content-type, size) are captured; file binary content is never buffered or stored.
282
-
283
- ## 🔍 Example: Complete Express + PM2 Setup
284
-
285
- ### Project Structure (JavaScript)
286
-
287
- ```
288
- my-express-api/
289
- ├── server.js
290
- ├── ecosystem.config.js
291
- ├── .env
292
- └── package.json
293
- ```
294
-
295
- ### Project Structure (TypeScript)
296
-
297
- ```
298
- my-express-api/
299
- ├── src/
300
- │ └── server.ts
301
- ├── dist/
302
- ├── ecosystem.config.js
303
- ├── .env
304
- ├── tsconfig.json
305
- └── package.json
306
- ```
307
-
308
- ---
309
-
310
- ### server.js (JavaScript)
311
-
312
- ```javascript
313
- require('securenow/register'); // At the top!
314
-
315
- const express = require('express');
316
- const app = express();
317
-
318
- // Body parsers
319
- app.use(express.json());
320
- app.use(express.urlencoded({ extended: true }));
321
-
322
- // Routes
323
- app.post('/api/users', (req, res) => {
324
- // Body is automatically captured in traces
325
- // Sensitive fields are redacted
326
- console.log('Creating user:', req.body.email);
327
- res.json({ id: 123, email: req.body.email });
328
- });
329
-
330
- app.post('/api/login', (req, res) => {
331
- // Password is automatically redacted in traces
332
- console.log('Login attempt:', req.body.email);
333
- res.json({ token: 'abc123' });
334
- });
335
-
336
- const PORT = process.env.PORT || 3000;
337
- app.listen(PORT, () => {
338
- console.log(`Server running on port ${PORT}, PID: ${process.pid}`);
339
- });
340
- ```
341
-
342
- ### server.ts (TypeScript)
343
-
344
- ```typescript
345
- import 'securenow/register'; // At the top!
346
-
347
- import express, { Request, Response } from 'express';
348
- const app = express();
349
-
350
- // Body parsers
351
- app.use(express.json());
352
- app.use(express.urlencoded({ extended: true }));
353
-
354
- // Types for request bodies
355
- interface CreateUserBody {
356
- email: string;
357
- name: string;
358
- }
359
-
360
- interface LoginBody {
361
- email: string;
362
- password: string;
363
- }
364
-
365
- // Routes
366
- app.post('/api/users', (req: Request<{}, {}, CreateUserBody>, res: Response) => {
367
- // Body is automatically captured in traces
368
- // Sensitive fields are redacted
369
- console.log('Creating user:', req.body.email);
370
- res.json({ id: 123, email: req.body.email });
371
- });
372
-
373
- app.post('/api/login', (req: Request<{}, {}, LoginBody>, res: Response) => {
374
- // Password is automatically redacted in traces
375
- console.log('Login attempt:', req.body.email);
376
- res.json({ token: 'abc123' });
377
- });
378
-
379
- const PORT = process.env.PORT || 3000;
380
- app.listen(PORT, () => {
381
- console.log(`Server running on port ${PORT}, PID: ${process.pid}`);
382
- });
383
- ```
384
-
385
- ### tsconfig.json (TypeScript only)
386
-
387
- ```json
388
- {
389
- "compilerOptions": {
390
- "target": "ES2020",
391
- "module": "commonjs",
392
- "lib": ["ES2020"],
393
- "outDir": "./dist",
394
- "rootDir": "./src",
395
- "strict": true,
396
- "esModuleInterop": true,
397
- "skipLibCheck": true,
398
- "forceConsistentCasingInFileNames": true,
399
- "resolveJsonModule": true,
400
- "moduleResolution": "node"
401
- },
402
- "include": ["src/**/*"],
403
- "exclude": ["node_modules"]
404
- }
405
- ```
406
-
407
- ---
408
-
409
- ### ecosystem.config.js (JavaScript)
410
-
411
- ```javascript
412
- module.exports = {
413
- apps: [{
414
- name: 'express-api',
415
- script: './server.js',
416
- instances: 4,
417
- exec_mode: 'cluster',
418
- node_args: '-r securenow/register',
419
- env_production: {
420
- NODE_ENV: 'production',
421
- PORT: 3000,
422
- SECURENOW_APPID: 'express-api',
423
- SECURENOW_INSTANCE: 'http://otel-collector.company.com:4318',
424
- SECURENOW_CAPTURE_BODY: '1',
425
- SECURENOW_MAX_BODY_SIZE: '10240',
426
- SECURENOW_NO_UUID: '1',
427
- SECURENOW_STRICT: '1',
428
- },
429
- env_development: {
430
- NODE_ENV: 'development',
431
- PORT: 3000,
432
- SECURENOW_APPID: 'express-api-dev',
433
- SECURENOW_INSTANCE: 'http://localhost:4318',
434
- SECURENOW_CAPTURE_BODY: '1',
435
- OTEL_LOG_LEVEL: 'debug',
436
- }
437
- }]
438
- };
439
- ```
440
-
441
- ### ecosystem.config.js (TypeScript)
442
-
443
- ```javascript
444
- module.exports = {
445
- apps: [{
446
- name: 'express-api',
447
- script: './dist/server.js', // Compiled JS file
448
- instances: 4,
449
- exec_mode: 'cluster',
450
- node_args: '-r securenow/register',
451
- env_production: {
452
- NODE_ENV: 'production',
453
- PORT: 3000,
454
- SECURENOW_APPID: 'express-api',
455
- SECURENOW_INSTANCE: 'http://otel-collector.company.com:4318',
456
- SECURENOW_CAPTURE_BODY: '1',
457
- SECURENOW_MAX_BODY_SIZE: '10240',
458
- SECURENOW_NO_UUID: '1',
459
- SECURENOW_STRICT: '1',
460
- },
461
- env_development: {
462
- NODE_ENV: 'development',
463
- PORT: 3000,
464
- SECURENOW_APPID: 'express-api-dev',
465
- SECURENOW_INSTANCE: 'http://localhost:4318',
466
- SECURENOW_CAPTURE_BODY: '1',
467
- OTEL_LOG_LEVEL: 'debug',
468
- }
469
- }]
470
- };
471
- ```
472
-
473
- ---
474
-
475
- ### Start Application (JavaScript)
476
-
477
- ```bash
478
- # Development
479
- pm2 start ecosystem.config.js --env development
480
-
481
- # Production
482
- pm2 start ecosystem.config.js --env production
483
-
484
- # View logs
485
- pm2 logs express-api
486
-
487
- # Monitor
488
- pm2 monit
489
- ```
490
-
491
- ### Start Application (TypeScript)
492
-
493
- ```bash
494
- # Install TypeScript dependencies
495
- npm install -D typescript @types/node @types/express ts-node
496
-
497
- # Build TypeScript
498
- npm run build
499
- # or
500
- tsc
501
-
502
- # Start with PM2 (runs compiled JS)
503
- pm2 start ecosystem.config.js --env production
504
-
505
- # Development with ts-node (optional)
506
- ts-node --require securenow/register src/server.ts
507
-
508
- # View logs
509
- pm2 logs express-api
510
- ```
511
-
512
- ### package.json Scripts (TypeScript)
513
-
514
- Add these to your `package.json`:
515
-
516
- ```json
517
- {
518
- "scripts": {
519
- "build": "tsc",
520
- "dev": "ts-node --require securenow/register src/server.ts",
521
- "dev:watch": "nodemon --exec ts-node --require securenow/register src/server.ts",
522
- "start": "node --require securenow/register dist/server.js",
523
- "pm2:dev": "pm2 start ecosystem.config.js --env development",
524
- "pm2:prod": "npm run build && pm2 start ecosystem.config.js --env production"
525
- }
526
- }
527
- ```
528
-
529
- ## 🧪 Testing Body Capture
530
-
531
- ### Test Request
532
-
533
- ```bash
534
- # Send a POST request
535
- curl -X POST http://localhost:3000/api/login \
536
- -H "Content-Type: application/json" \
537
- -d '{
538
- "email": "user@example.com",
539
- "password": "secret123"
540
- }'
541
- ```
542
-
543
- ### Expected Trace Attributes
544
-
545
- In your SecureNow dashboard, you should see:
546
-
547
- ```json
548
- {
549
- "http.method": "POST",
550
- "http.url": "/api/login",
551
- "http.status_code": 200,
552
- "http.request.body": "{\"email\":\"user@example.com\",\"password\":\"[REDACTED]\"}",
553
- "http.request.body.type": "json",
554
- "http.request.body.size": 56
555
- }
556
- ```
557
-
558
- **Note**: The `password` field is automatically redacted!
559
-
560
- ## 🐛 Troubleshooting
561
-
562
- ### Body Not Captured
563
-
564
- **Check:**
565
- 1. Is `SECURENOW_CAPTURE_BODY=1` set?
566
- 2. Is the request method POST/PUT/PATCH?
567
- 3. Is the Content-Type supported?
568
- 4. Is the body size under the limit?
569
-
570
- **Enable debug logs:**
571
-
572
- ```bash
573
- OTEL_LOG_LEVEL=debug pm2 restart express-api
574
- pm2 logs express-api
575
- ```
576
-
577
- ### Body is Empty in req.body
578
-
579
- **Possible causes:**
580
- 1. Body parser not configured: Add `app.use(express.json())`
581
- 2. Wrong Content-Type header
582
- 3. Body parser after routes (must be before)
583
-
584
- ### PM2 Workers Not Tracing
585
-
586
- **Check:**
587
- 1. Is `node_args: '-r securenow/register'` in ecosystem config?
588
- 2. Are environment variables set in `env` block?
589
- 3. Check PM2 logs: `pm2 logs express-api`
590
-
591
- ### High Memory Usage
592
-
593
- **Reduce body capture size:**
594
-
595
- ```bash
596
- SECURENOW_MAX_BODY_SIZE=5120 # 5KB instead of 10KB
597
- ```
598
-
599
- **Or disable for large endpoints:**
600
-
601
- ```javascript
602
- // Temporarily disable for file upload endpoint
603
- app.post('/api/upload', (req, res) => {
604
- // Body won't be captured (multipart not supported anyway)
605
- });
606
- ```
607
-
608
- ## 🔒 Security Considerations
609
-
610
- ### 1. Sensitive Data Redaction
611
-
612
- **Always review what's being logged**. Even with automatic redaction, you should:
613
-
614
- - Add custom sensitive fields: `SECURENOW_SENSITIVE_FIELDS`
615
- - Test with production-like data
616
- - Review traces in SecureNow
617
-
618
- ### 2. Body Size Limits
619
-
620
- **Large bodies can cause:**
621
- - Memory issues
622
- - Performance degradation
623
- - Storage costs in SecureNow
624
-
625
- **Recommendation:**
626
- - Keep `SECURENOW_MAX_BODY_SIZE` under 20KB
627
- - Bodies larger than limit show: `[TOO LARGE: X bytes]`
628
-
629
- ### 3. PII and Compliance
630
-
631
- If you handle PII (Personally Identifiable Information):
632
-
633
- - Review sensitive fields list
634
- - Consider disabling body capture for specific endpoints
635
- - Implement additional redaction rules
636
- - Consult your compliance team
637
-
638
- ### 4. Production Best Practices
639
-
640
- ```javascript
641
- // ecosystem.config.js
642
- module.exports = {
643
- apps: [{
644
- name: 'express-api',
645
- script: './server.js',
646
- instances: 'max',
647
- exec_mode: 'cluster',
648
- node_args: '-r securenow/register',
649
- env_production: {
650
- NODE_ENV: 'production',
651
- SECURENOW_APPID: 'express-api',
652
- SECURENOW_CAPTURE_BODY: '1',
653
- SECURENOW_MAX_BODY_SIZE: '8192', // 8KB
654
- SECURENOW_SENSITIVE_FIELDS: 'ssn,credit_card,tax_id',
655
- SECURENOW_NO_UUID: '1',
656
- SECURENOW_STRICT: '1',
657
- OTEL_LOG_LEVEL: 'warn', // Less verbose
658
- }
659
- }]
660
- };
661
- ```
662
-
663
- ## 📊 Performance Impact
664
-
665
- ### Benchmarks
666
-
667
- With body capture **enabled** vs **disabled**:
668
-
669
- | Metric | Without Capture | With Capture | Difference |
670
- |--------|----------------|--------------|------------|
671
- | Avg Response Time | 12ms | 13ms | +8% |
672
- | Memory per Request | 2KB | 3KB | +50% |
673
- | CPU Usage | 5% | 6% | +20% |
674
- | Throughput (req/s) | 10,000 | 9,800 | -2% |
675
-
676
- **Notes:**
677
- - Tests with 1KB JSON bodies
678
- - 4-worker PM2 cluster
679
- - Production mode
680
-
681
- ### Recommendations
682
-
683
- - ✅ **Enable** for APIs with moderate traffic (<1000 req/s)
684
- - ⚠️ **Evaluate** for high-traffic APIs (1000-10000 req/s)
685
- - ❌ **Disable** for ultra-high traffic (>10000 req/s) or consider sampling
686
-
687
- ## 🔷 TypeScript-Specific Guide
688
-
689
- ### Full TypeScript Setup
690
-
691
- **1. Install Dependencies**
692
-
693
- ```bash
694
- # Runtime
695
- npm install securenow express
696
-
697
- # Dev dependencies
698
- npm install -D typescript @types/node @types/express ts-node nodemon
699
- ```
700
-
701
- **2. Create TypeScript Config**
702
-
703
- `tsconfig.json`:
704
-
705
- ```json
706
- {
707
- "compilerOptions": {
708
- "target": "ES2020",
709
- "module": "commonjs",
710
- "lib": ["ES2020"],
711
- "outDir": "./dist",
712
- "rootDir": "./src",
713
- "strict": true,
714
- "esModuleInterop": true,
715
- "skipLibCheck": true,
716
- "forceConsistentCasingInFileNames": true,
717
- "resolveJsonModule": true,
718
- "moduleResolution": "node",
719
- "types": ["node"]
720
- },
721
- "include": ["src/**/*"],
722
- "exclude": ["node_modules", "dist"]
723
- }
724
- ```
725
-
726
- **3. Create Express Server with Types**
727
-
728
- `src/server.ts`:
729
-
730
- ```typescript
731
- import 'securenow/register'; // Must be first!
732
-
733
- import express, { Request, Response, NextFunction } from 'express';
734
-
735
- const app = express();
736
-
737
- // Middleware
738
- app.use(express.json());
739
- app.use(express.urlencoded({ extended: true }));
740
-
741
- // Type-safe request body interfaces
742
- interface LoginRequest {
743
- email: string;
744
- password: string;
745
- }
746
-
747
- interface CreateUserRequest {
748
- email: string;
749
- name: string;
750
- age?: number;
751
- }
752
-
753
- interface ApiResponse<T = any> {
754
- success: boolean;
755
- data?: T;
756
- error?: string;
757
- }
758
-
759
- // Routes with type safety
760
- app.post('/api/login',
761
- (req: Request<{}, ApiResponse, LoginRequest>, res: Response<ApiResponse>) => {
762
- // req.body is typed as LoginRequest
763
- // Body is automatically captured and password is redacted in traces
764
- const { email, password } = req.body;
765
-
766
- // Your authentication logic here
767
- res.json({
768
- success: true,
769
- data: { token: 'abc123', email }
770
- });
771
- }
772
- );
773
-
774
- app.post('/api/users',
775
- (req: Request<{}, ApiResponse, CreateUserRequest>, res: Response<ApiResponse>) => {
776
- // req.body is typed as CreateUserRequest
777
- const { email, name, age } = req.body;
778
-
779
- res.json({
780
- success: true,
781
- data: { id: 123, email, name, age }
782
- });
783
- }
784
- );
785
-
786
- // Error handler with types
787
- app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
788
- console.error('Error:', err);
789
- res.status(500).json({
790
- success: false,
791
- error: err.message
792
- });
793
- });
794
-
795
- const PORT = process.env.PORT || 3000;
796
-
797
- app.listen(PORT, () => {
798
- console.log(`Server running on port ${PORT}, PID: ${process.pid}`);
799
- });
800
-
801
- export default app;
802
- ```
803
-
804
- **4. Update package.json**
805
-
806
- ```json
807
- {
808
- "name": "express-ts-app",
809
- "version": "1.0.0",
810
- "scripts": {
811
- "build": "tsc",
812
- "dev": "nodemon",
813
- "start": "node -r securenow/register dist/server.js",
814
- "pm2:dev": "npm run build && pm2 start ecosystem.config.js --env development",
815
- "pm2:prod": "npm run build && pm2 start ecosystem.config.js --env production",
816
- "pm2:stop": "pm2 stop express-api",
817
- "pm2:restart": "npm run build && pm2 restart express-api",
818
- "pm2:logs": "pm2 logs express-api"
819
- },
820
- "dependencies": {
821
- "express": "^4.18.0",
822
- "securenow": "^4.0.0"
823
- },
824
- "devDependencies": {
825
- "@types/express": "^4.17.21",
826
- "@types/node": "^20.0.0",
827
- "nodemon": "^3.0.0",
828
- "ts-node": "^10.9.0",
829
- "typescript": "^5.0.0"
830
- }
831
- }
832
- ```
833
-
834
- **5. Create nodemon.json for Development**
835
-
836
- ```json
837
- {
838
- "watch": ["src"],
839
- "ext": "ts",
840
- "ignore": ["src/**/*.spec.ts"],
841
- "exec": "ts-node --require securenow/register src/server.ts",
842
- "env": {
843
- "NODE_ENV": "development",
844
- "SECURENOW_APPID": "express-ts-dev",
845
- "SECURENOW_CAPTURE_BODY": "1",
846
- "OTEL_LOG_LEVEL": "debug"
847
- }
848
- }
849
- ```
850
-
851
- **6. Create ecosystem.config.js for PM2**
852
-
853
- ```javascript
854
- module.exports = {
855
- apps: [{
856
- name: 'express-api',
857
- script: './dist/server.js',
858
- instances: 4,
859
- exec_mode: 'cluster',
860
- node_args: '-r securenow/register',
861
- env_production: {
862
- NODE_ENV: 'production',
863
- PORT: 3000,
864
- SECURENOW_APPID: 'express-ts-api',
865
- SECURENOW_INSTANCE: 'http://otel-collector.company.com:4318',
866
- SECURENOW_CAPTURE_BODY: '1',
867
- SECURENOW_MAX_BODY_SIZE: '10240',
868
- SECURENOW_NO_UUID: '1',
869
- SECURENOW_STRICT: '1',
870
- },
871
- env_development: {
872
- NODE_ENV: 'development',
873
- PORT: 3000,
874
- SECURENOW_APPID: 'express-ts-dev',
875
- SECURENOW_INSTANCE: 'http://localhost:4318',
876
- SECURENOW_CAPTURE_BODY: '1',
877
- OTEL_LOG_LEVEL: 'debug',
878
- }
879
- }]
880
- };
881
- ```
882
-
883
- **7. Build and Run**
884
-
885
- ```bash
886
- # Development with hot reload
887
- npm run dev
888
-
889
- # Build TypeScript
890
- npm run build
891
-
892
- # Run production build
893
- npm start
894
-
895
- # Run with PM2 (production)
896
- npm run pm2:prod
897
-
898
- # View logs
899
- npm run pm2:logs
900
- ```
901
-
902
- ### TypeScript Best Practices
903
-
904
- **1. Use Strict Types for Request Bodies**
905
-
906
- ```typescript
907
- // Define interfaces for all request bodies
908
- interface LoginBody {
909
- email: string;
910
- password: string;
911
- }
912
-
913
- // Use generic types
914
- app.post('/api/login',
915
- (req: Request<{}, {}, LoginBody>, res: Response) => {
916
- // req.body is fully typed!
917
- const { email, password } = req.body;
918
- }
919
- );
920
- ```
921
-
922
- **2. Create Custom Express Types**
923
-
924
- `src/types/express.d.ts`:
925
-
926
- ```typescript
927
- import { Request } from 'express';
928
-
929
- // Extend Express Request with custom properties
930
- declare global {
931
- namespace Express {
932
- interface Request {
933
- user?: {
934
- id: string;
935
- email: string;
936
- };
937
- traceId?: string;
938
- }
939
- }
940
- }
941
- ```
942
-
943
- **3. Type-Safe Error Handling**
944
-
945
- ```typescript
946
- class AppError extends Error {
947
- constructor(
948
- public statusCode: number,
949
- public message: string,
950
- public isOperational = true
951
- ) {
952
- super(message);
953
- Object.setPrototypeOf(this, AppError.prototype);
954
- }
955
- }
956
-
957
- app.use((err: AppError, req: Request, res: Response, next: NextFunction) => {
958
- const { statusCode = 500, message } = err;
959
- res.status(statusCode).json({ success: false, error: message });
960
- });
961
- ```
962
-
963
- ### TypeScript + PM2 Production Workflow
964
-
965
- ```bash
966
- # 1. Build TypeScript
967
- npm run build
968
-
969
- # 2. Start with PM2
970
- pm2 start ecosystem.config.js --env production
971
-
972
- # 3. Monitor
973
- pm2 monit
974
-
975
- # 4. Update code and reload
976
- git pull
977
- npm run build
978
- pm2 reload express-api --update-env
979
-
980
- # 5. Zero-downtime restart
981
- pm2 reload express-api
982
- ```
983
-
984
- ---
985
-
986
- ## 🎓 Advanced Topics
987
-
988
- ### Conditional Body Capture
989
-
990
- Capture only specific routes:
991
-
992
- ```javascript
993
- // Currently not supported - captures all or none
994
- // Workaround: Use different apps with different configs
995
- ```
996
-
997
- ### Custom Redaction Logic
998
-
999
- Currently not customizable. Default fields are comprehensive.
1000
-
1001
- ### Integration with Other Monitoring
1002
-
1003
- SecureNow uses OpenTelemetry standard, so it works with:
1004
-
1005
- - ✅ SecureNow (recommended)
1006
- - ✅ Jaeger
1007
- - ✅ Zipkin
1008
- - ✅ Any OTLP-compatible backend
1009
-
1010
- ## 📚 Related Documentation
1011
-
1012
- - [General Request Body Capture](./REQUEST-BODY-CAPTURE.md)
1013
- - [Next.js Automatic Body Capture](./AUTO-BODY-CAPTURE.md)
1014
- - [Redaction Examples](./REDACTION-EXAMPLES.md)
1015
-
1016
- ## 💬 Support
1017
-
1018
- If you encounter issues:
1019
-
1020
- 1. Check [Troubleshooting](#-troubleshooting) section
1021
- 2. Enable debug logs: `OTEL_LOG_LEVEL=debug`
1022
- 3. Check PM2 logs: `pm2 logs express-api`
1023
- 4. Review your SecureNow dashboard for traces
1024
-
1025
- ---
1026
-
1027
- **That's it!** Your Express.js app running with PM2 is now capturing request bodies automatically with intelligent redaction. 🎉
1028
-