securenow 7.5.1 → 7.6.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/CONSUMING-APPS-GUIDE.md +2 -0
- package/NPM_README.md +201 -237
- package/README.md +73 -26
- package/SKILL-API.md +209 -205
- package/SKILL-CLI.md +71 -64
- package/app-config.js +479 -83
- package/cli/apiKey.js +1 -1
- package/cli/apps.js +1 -1
- package/cli/config.js +31 -12
- package/cli/credentials.js +88 -0
- package/cli/diagnostics.js +68 -104
- package/cli/firewall.js +29 -14
- package/cli/init.js +208 -206
- package/cli/monitor.js +107 -43
- package/cli/security.js +24 -12
- package/cli/utils.js +2 -1
- package/cli.js +71 -39
- package/console-instrumentation.js +1 -1
- package/docs/ENVIRONMENT-VARIABLES.md +137 -863
- package/docs/ENVIRONMENTS.md +60 -0
- package/docs/EXPRESS-SETUP-GUIDE.md +3 -0
- package/docs/FIREWALL-GUIDE.md +3 -0
- package/docs/INDEX.md +6 -8
- package/docs/LOGGING-GUIDE.md +3 -0
- package/docs/MCP-GUIDE.md +8 -0
- package/docs/NEXTJS-GUIDE.md +3 -0
- package/docs/NEXTJS-QUICKSTART.md +24 -16
- package/docs/NUXT-GUIDE.md +3 -0
- package/docs/QUICKSTART-BODY-CAPTURE.md +3 -0
- package/docs/REQUEST-BODY-CAPTURE.md +3 -0
- package/firewall-cloud.js +10 -10
- package/firewall-only.js +25 -23
- package/firewall.js +47 -29
- package/free-trial-banner.js +1 -1
- package/mcp/catalog.js +104 -17
- package/nextjs-auto-capture.d.ts +7 -4
- package/nextjs-auto-capture.js +7 -7
- package/nextjs-middleware.js +4 -3
- package/nextjs-wrapper.js +6 -6
- package/nextjs.d.ts +36 -25
- package/nextjs.js +47 -55
- package/nuxt-server-plugin.mjs +35 -51
- package/nuxt.d.ts +29 -23
- package/package.json +1 -1
- package/postinstall.js +27 -61
- package/register.d.ts +19 -33
- package/register.js +8 -8
- package/resolve-ip.js +4 -5
- package/tracing.d.ts +21 -19
- package/tracing.js +34 -42
package/SKILL-API.md
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Instrument any Node.js application with OpenTelemetry tracing, structured logging, request body capture, and a multi-layer IP firewall. Supports Express, Fastify, NestJS, Koa, Hapi, Next.js, Nuxt 3, Vite (browser), and raw `http.createServer` — with zero code changes for most setups.
|
|
4
4
|
|
|
5
|
-
**CLI parity:** every capability exposed below (redaction, CIDR matching, log/span emission, firewall preload, config inspection) has an equivalent `securenow` CLI command. See [SKILL-CLI.md](./SKILL-CLI.md) for the terminal surface.
|
|
6
|
-
|
|
7
|
-
**MCP parity (v7.5+):** `npx securenow mcp` starts a local stdio MCP server for Codex, Claude, and other MCP clients. It reuses the same `.securenow/credentials.json` file as the CLI/SDK and exposes SecureNow tools, bundled docs resources, and setup prompts to agents.
|
|
5
|
+
**CLI parity:** every capability exposed below (redaction, CIDR matching, log/span emission, firewall preload, config inspection) has an equivalent `securenow` CLI command. See [SKILL-CLI.md](./SKILL-CLI.md) for the terminal surface.
|
|
6
|
+
|
|
7
|
+
**MCP parity (v7.5+):** `npx securenow mcp` starts a local stdio MCP server for Codex, Claude, and other MCP clients. It reuses the same `.securenow/credentials.json` file as the CLI/SDK and exposes SecureNow tools, bundled docs resources, and setup prompts to agents.
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
|
-
npm install securenow
|
|
12
|
+
npm install securenow@latest
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
### Install This Skill in Cursor
|
|
@@ -18,14 +18,18 @@ Save this file as `.cursor/skills/securenow-api/SKILL.md` in your project. Your
|
|
|
18
18
|
|
|
19
19
|
## Quick Start — Any Node.js Framework
|
|
20
20
|
|
|
21
|
-
### 1.
|
|
21
|
+
### 1. Install, Login, And Init
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
24
|
+
npm install securenow@latest
|
|
25
|
+
node -p "require('./node_modules/securenow/package.json').version"
|
|
26
|
+
npx securenow version
|
|
27
|
+
npx securenow login
|
|
28
|
+
npx securenow init
|
|
27
29
|
```
|
|
28
30
|
|
|
31
|
+
Use `securenow@7.5.1` or newer. Start authentication with `npx securenow login`; do not manually open auth URLs, because the CLI generates the callback/state values. The login flow lets the user pick or create an app, enables the app firewall by default, writes `.securenow/credentials.json`, and `init` scaffolds the framework integration.
|
|
32
|
+
|
|
29
33
|
### 2. Run With Instrumentation
|
|
30
34
|
|
|
31
35
|
**Option A — CLI (recommended):**
|
|
@@ -43,24 +47,24 @@ node -r securenow/register src/index.js
|
|
|
43
47
|
**Option C — Auto-setup for Next.js:**
|
|
44
48
|
|
|
45
49
|
```bash
|
|
46
|
-
npx securenow init
|
|
50
|
+
npx securenow init
|
|
47
51
|
```
|
|
48
52
|
|
|
49
|
-
That's it. Traces and
|
|
53
|
+
That's it. Traces, logs, request body capture, multipart metadata capture, and firewall enforcement are on by default. No code changes for Express, Fastify, NestJS, Koa, Hapi, and raw Node.
|
|
50
54
|
|
|
51
|
-
### 3. Firewall Is Enabled by Default
|
|
55
|
+
### 3. Firewall Is Enabled by Default
|
|
52
56
|
|
|
53
|
-
Since v7.
|
|
54
|
-
the user picks or creates an app. The firewall key lives in your credentials
|
|
55
|
-
file — no env var required:
|
|
57
|
+
Since v7.5.1, the browser login flow connects the firewall automatically after
|
|
58
|
+
the user picks or creates an app. The firewall key lives in your credentials
|
|
59
|
+
file — no env var required:
|
|
56
60
|
|
|
57
61
|
```bash
|
|
58
|
-
npx securenow login # pick/create app; firewall key is minted automatically
|
|
59
|
-
# or, if you already have one:
|
|
60
|
-
npx securenow api-key set snk_live_abc123...
|
|
62
|
+
npx securenow login # pick/create app; firewall key is minted automatically
|
|
63
|
+
# or, if you already have one:
|
|
64
|
+
npx securenow api-key set snk_live_abc123...
|
|
61
65
|
```
|
|
62
66
|
|
|
63
|
-
Both paths write the key to `.securenow/credentials.json` (auto-gitignored) and the firewall activates on next start.
|
|
67
|
+
Both paths write the key to `.securenow/credentials.json` (auto-gitignored) and the firewall activates on next start. For production, run `npx securenow credentials runtime --env production` and mount/copy the tokenless file as `.securenow/credentials.json`.
|
|
64
68
|
|
|
65
69
|
The firewall syncs your blocklist and enforces it on every request — zero code changes.
|
|
66
70
|
|
|
@@ -110,77 +114,86 @@ npx securenow run app.js
|
|
|
110
114
|
// ecosystem.config.cjs
|
|
111
115
|
module.exports = {
|
|
112
116
|
apps: [{
|
|
113
|
-
name: 'my-app',
|
|
114
|
-
script: './app.js',
|
|
115
|
-
instances: 4,
|
|
116
|
-
node_args: '-r securenow/register',
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
},
|
|
122
|
-
}],
|
|
123
|
-
};
|
|
124
|
-
```
|
|
117
|
+
name: 'my-app',
|
|
118
|
+
script: './app.js',
|
|
119
|
+
instances: 4,
|
|
120
|
+
node_args: '-r securenow/register',
|
|
121
|
+
// Reads .securenow/credentials.json from the project root.
|
|
122
|
+
}],
|
|
123
|
+
};
|
|
124
|
+
```
|
|
125
125
|
|
|
126
126
|
**Docker:**
|
|
127
127
|
|
|
128
|
-
```dockerfile
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
```
|
|
128
|
+
```dockerfile
|
|
129
|
+
COPY .securenow/credentials.json ./.securenow/credentials.json
|
|
130
|
+
CMD ["node", "-r", "securenow/register", "app.js"]
|
|
131
|
+
```
|
|
133
132
|
|
|
134
133
|
---
|
|
135
134
|
|
|
136
|
-
### Next.js
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
**1. `next.config.js`** (or `.mjs` / `.ts`):
|
|
141
|
-
|
|
142
|
-
```javascript
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
`
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
|
|
135
|
+
### Next.js
|
|
136
|
+
|
|
137
|
+
Run `npx securenow init` first. It creates the straightforward integration below when files are missing, and prints a Codex/Claude-ready merge prompt when existing files need careful edits.
|
|
138
|
+
|
|
139
|
+
**1. `next.config.js`** (or `.mjs` / `.ts`):
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
const nextConfig = {
|
|
143
|
+
serverExternalPackages: ['securenow'],
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
export default nextConfig;
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
For Next.js < 15, add `securenow` to `experimental.serverComponentsExternalPackages` instead.
|
|
150
|
+
|
|
151
|
+
**2. `instrumentation.ts`** (or `.js`, can be in `src/`):
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
import { createRequire } from 'node:module';
|
|
155
|
+
|
|
156
|
+
const require = createRequire(import.meta.url);
|
|
157
|
+
|
|
158
|
+
export async function register() {
|
|
159
|
+
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
160
|
+
const { registerSecureNow } = require('securenow/nextjs');
|
|
161
|
+
registerSecureNow({ captureBody: true });
|
|
162
|
+
require('securenow/nextjs-auto-capture');
|
|
163
|
+
}
|
|
164
|
+
```
|
|
164
165
|
|
|
165
166
|
`registerSecureNow(options?)` accepts:
|
|
166
167
|
|
|
167
|
-
```typescript
|
|
168
|
-
interface RegisterOptions {
|
|
169
|
-
serviceName?: string; // override
|
|
170
|
-
endpoint?: string; // override
|
|
171
|
-
noUuid?: boolean; // override
|
|
172
|
-
captureBody?: boolean; // override
|
|
173
|
-
}
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-node`.
|
|
177
|
-
|
|
178
|
-
**3.
|
|
179
|
-
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
```typescript
|
|
169
|
+
interface RegisterOptions {
|
|
170
|
+
serviceName?: string; // override credentials app key/name
|
|
171
|
+
endpoint?: string; // override credentials app instance
|
|
172
|
+
noUuid?: boolean; // override credentials config.runtime.noUuid
|
|
173
|
+
captureBody?: boolean; // override credentials config.capture.body
|
|
174
|
+
}
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-node`.
|
|
178
|
+
|
|
179
|
+
**3. Credentials:**
|
|
180
|
+
|
|
181
|
+
```json
|
|
182
|
+
{
|
|
183
|
+
"app": {
|
|
184
|
+
"key": "<uuid>",
|
|
185
|
+
"name": "my-nextjs-app",
|
|
186
|
+
"instance": "https://freetrial.securenow.ai:4318"
|
|
187
|
+
},
|
|
188
|
+
"config": {
|
|
189
|
+
"logging": { "enabled": true },
|
|
190
|
+
"capture": { "body": true, "multipart": true, "maxBodySize": 10240 },
|
|
191
|
+
"firewall": { "enabled": true }
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Local development and production do not need `.env.local`; `npx securenow login` and `npx securenow init` keep `.securenow/credentials.json` filled and gitignored. For production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json`.
|
|
184
197
|
|
|
185
198
|
#### Next.js Body Capture
|
|
186
199
|
|
|
@@ -188,15 +201,18 @@ SECURENOW_INSTANCE=https://your-collector:4318
|
|
|
188
201
|
|
|
189
202
|
Add to your `instrumentation.ts`:
|
|
190
203
|
|
|
191
|
-
```typescript
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
}
|
|
199
|
-
|
|
204
|
+
```typescript
|
|
205
|
+
import { createRequire } from 'node:module';
|
|
206
|
+
|
|
207
|
+
const require = createRequire(import.meta.url);
|
|
208
|
+
|
|
209
|
+
export async function register() {
|
|
210
|
+
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
211
|
+
const { registerSecureNow } = require('securenow/nextjs');
|
|
212
|
+
registerSecureNow({ captureBody: true });
|
|
213
|
+
require('securenow/nextjs-auto-capture');
|
|
214
|
+
}
|
|
215
|
+
```
|
|
200
216
|
|
|
201
217
|
**Option B — Middleware:**
|
|
202
218
|
|
|
@@ -219,10 +235,11 @@ export const POST = withSecureNow(async (req) => {
|
|
|
219
235
|
#### Next.js with `securenow init`
|
|
220
236
|
|
|
221
237
|
```bash
|
|
222
|
-
npx securenow
|
|
238
|
+
npx securenow login
|
|
239
|
+
npx securenow init
|
|
223
240
|
```
|
|
224
241
|
|
|
225
|
-
Auto-detects Next.js, creates `instrumentation.ts`,
|
|
242
|
+
Auto-detects Next.js, creates `instrumentation.ts`, adds `serverExternalPackages: ['securenow']` when safe, and reuses the app, instance, firewall key, and secure defaults in `.securenow/credentials.json`. If files already exist, it prints an agent-ready prompt with the exact edits to propose.
|
|
226
243
|
|
|
227
244
|
---
|
|
228
245
|
|
|
@@ -232,21 +249,14 @@ Auto-detects Next.js, creates `instrumentation.ts`, suggests `next.config` chang
|
|
|
232
249
|
|
|
233
250
|
```typescript
|
|
234
251
|
export default defineNuxtConfig({
|
|
235
|
-
modules: ['securenow/nuxt'],
|
|
236
|
-
securenow: {
|
|
237
|
-
// optional overrides (defaults come from
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
```bash
|
|
245
|
-
SECURENOW_APPID=my-nuxt-app
|
|
246
|
-
SECURENOW_INSTANCE=https://your-collector:4318
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
The Nuxt module auto-configures Nitro externals, runtime config, and a server plugin that sets up OTel tracing + logging + firewall.
|
|
252
|
+
modules: ['securenow/nuxt'],
|
|
253
|
+
securenow: {
|
|
254
|
+
// optional overrides (defaults come from .securenow/credentials.json)
|
|
255
|
+
},
|
|
256
|
+
});
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
The Nuxt module auto-configures Nitro externals, runtime config, and a server plugin that sets up OTel tracing + logging + firewall. Local and production app identity, firewall key, and secure defaults come from `.securenow/credentials.json`.
|
|
250
260
|
|
|
251
261
|
---
|
|
252
262
|
|
|
@@ -267,7 +277,7 @@ Instruments document load, fetch, XMLHttpRequest, and user interactions with bro
|
|
|
267
277
|
|
|
268
278
|
## Firewall — Multi-Layer IP Blocking
|
|
269
279
|
|
|
270
|
-
The firewall auto-activates once an API key is resolvable and the app firewall toggle is on. Since **v7.
|
|
280
|
+
The firewall auto-activates once an API key is resolvable and the app firewall toggle is on. Since **v7.5.1**, `npx securenow login` enables the selected app firewall by default and writes the scoped key to `.securenow/credentials.json`; `securenow api-key set` can still write/rotate the key later. Production should use the tokenless file generated by `securenow credentials runtime --env production`. Resolution order: project `./.securenow/credentials.json` -> global `~/.securenow/credentials.json`; legacy env vars are fallback-only for existing deployments.
|
|
271
281
|
|
|
272
282
|
```
|
|
273
283
|
Layer 4: Cloud/Edge WAF → blocked at CDN (Cloudflare, AWS WAF, GCP Cloud Armor)
|
|
@@ -279,16 +289,13 @@ Layer 1: HTTP Handler → 403 JSON response (always active)
|
|
|
279
289
|
### Activate
|
|
280
290
|
|
|
281
291
|
```bash
|
|
282
|
-
# Zero-config (recommended) — writes the key to .securenow/credentials.json
|
|
283
|
-
npx securenow login # pick/create app; firewall connects automatically
|
|
292
|
+
# Zero-config (recommended) — writes the key to .securenow/credentials.json
|
|
293
|
+
npx securenow login # pick/create app; firewall connects automatically
|
|
284
294
|
# or, if you already have a key:
|
|
285
295
|
npx securenow api-key set snk_live_abc123...
|
|
286
296
|
|
|
287
|
-
#
|
|
288
|
-
|
|
289
|
-
SECURENOW_FIREWALL_IPTABLES=1 # opt-in Layer 3 (Linux, needs root)
|
|
290
|
-
SECURENOW_FIREWALL_CLOUD=cloudflare # opt-in Layer 4
|
|
291
|
-
# SECURENOW_API_KEY=snk_live_... # still honored; only wins if it starts with snk_live_
|
|
297
|
+
# Production runtime file:
|
|
298
|
+
npx securenow credentials runtime --env production
|
|
292
299
|
```
|
|
293
300
|
|
|
294
301
|
### Firewall-Only Mode (No Tracing Overhead)
|
|
@@ -304,13 +311,14 @@ Loads only dotenv + firewall. No OpenTelemetry, no tracing, no external packages
|
|
|
304
311
|
|
|
305
312
|
### Programmatic Firewall API
|
|
306
313
|
|
|
307
|
-
```javascript
|
|
308
|
-
const firewall = require('securenow/firewall');
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
+
```javascript
|
|
315
|
+
const firewall = require('securenow/firewall');
|
|
316
|
+
const appConfig = require('securenow/app-config');
|
|
317
|
+
|
|
318
|
+
await firewall.init({
|
|
319
|
+
...appConfig.resolveFirewallOptions(),
|
|
320
|
+
apiUrl: 'https://api.securenow.ai',
|
|
321
|
+
syncInterval: 300, // full sync every 5 min
|
|
314
322
|
versionCheckInterval: 10, // lightweight version check every 10s
|
|
315
323
|
failMode: 'open', // 'open' or 'closed'
|
|
316
324
|
statusCode: 403,
|
|
@@ -440,7 +448,7 @@ const safe = redactSensitiveData({ username: 'alice', password: 's3cret', token:
|
|
|
440
448
|
|
|
441
449
|
**Auto-redacted fields:** `password`, `passwd`, `pwd`, `secret`, `token`, `api_key`, `apikey`, `access_token`, `auth`, `credentials`, `mysql_pwd`, `stripeToken`, `card`, `cardnumber`, `ccv`, `cvc`, `cvv`, `ssn`, `pin`.
|
|
442
450
|
|
|
443
|
-
Add custom fields via `SECURENOW_SENSITIVE_FIELDS=field1,field2
|
|
451
|
+
Add custom fields via `config.capture.sensitiveFields` in `.securenow/credentials.json`; `SECURENOW_SENSITIVE_FIELDS=field1,field2` is a legacy fallback for existing installs.
|
|
444
452
|
|
|
445
453
|
**CLI equivalent** (for piping, scripts, debugging what a payload looks like post-redaction):
|
|
446
454
|
|
|
@@ -451,20 +459,22 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
451
459
|
|
|
452
460
|
---
|
|
453
461
|
|
|
454
|
-
##
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
|
461
|
-
|
|
462
|
+
## Credentials Configuration
|
|
463
|
+
|
|
464
|
+
Local development and production use `.securenow/credentials.json`. Every setting below lives under `app` or `config`; `npx securenow credentials runtime --env production` creates a tokenless production file with the same structure. Environment variables are legacy fallbacks only.
|
|
465
|
+
|
|
466
|
+
### App Identity
|
|
467
|
+
|
|
468
|
+
| Variable | Description | Default |
|
|
469
|
+
|----------|-------------|---------|
|
|
470
|
+
| `SECURENOW_APPID` | Legacy fallback for `app.key` / service name | from credentials file, then package name |
|
|
471
|
+
| `SECURENOW_INSTANCE` | Legacy fallback for `app.instance` / OTLP collector base URL | from credentials file, then `https://freetrial.securenow.ai:4318` |
|
|
462
472
|
|
|
463
473
|
### Service Naming
|
|
464
474
|
|
|
465
475
|
| Variable | Description | Default |
|
|
466
476
|
|----------|-------------|---------|
|
|
467
|
-
| `OTEL_SERVICE_NAME` |
|
|
477
|
+
| `OTEL_SERVICE_NAME` | Legacy fallback for `app.name` | — |
|
|
468
478
|
| `SECURENOW_NO_UUID` | `1` to use exact app ID without UUID suffix | `0` |
|
|
469
479
|
| `SECURENOW_STRICT` | `1` to exit if APPID missing in PM2 cluster | `0` |
|
|
470
480
|
|
|
@@ -472,9 +482,9 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
472
482
|
|
|
473
483
|
| Variable | Description | Default |
|
|
474
484
|
|----------|-------------|---------|
|
|
475
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT` |
|
|
476
|
-
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` |
|
|
477
|
-
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` |
|
|
485
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | Legacy fallback for `config.otel.endpoint` | — |
|
|
486
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Legacy fallback for `config.otel.tracesEndpoint` | `{instance}/v1/traces` |
|
|
487
|
+
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Legacy fallback for `config.otel.logsEndpoint` | `{instance}/v1/logs` |
|
|
478
488
|
| `OTEL_EXPORTER_OTLP_HEADERS` | Comma-separated `key=value` headers for OTLP requests | — |
|
|
479
489
|
|
|
480
490
|
### Behavior
|
|
@@ -482,21 +492,21 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
482
492
|
| Variable | Description | Default |
|
|
483
493
|
|----------|-------------|---------|
|
|
484
494
|
| `SECURENOW_LOGGING_ENABLED` | Enable OTLP log export | `1` |
|
|
485
|
-
| `SECURENOW_CAPTURE_BODY` | Capture HTTP request bodies | `1` |
|
|
495
|
+
| `SECURENOW_CAPTURE_BODY` | Capture HTTP request bodies | `1` |
|
|
486
496
|
| `SECURENOW_MAX_BODY_SIZE` | Max body size in bytes | `10240` |
|
|
487
|
-
| `SECURENOW_CAPTURE_MULTIPART` | Capture multipart/form-data (streaming, metadata only) | `1` |
|
|
497
|
+
| `SECURENOW_CAPTURE_MULTIPART` | Capture multipart/form-data (streaming, metadata only) | `1` |
|
|
488
498
|
| `SECURENOW_SENSITIVE_FIELDS` | Comma-separated extra fields to redact | — |
|
|
489
499
|
| `SECURENOW_DISABLE_INSTRUMENTATIONS` | Comma-separated packages to skip (e.g. `fs,dns`) | — |
|
|
490
500
|
| `SECURENOW_TEST_SPAN` | `1` to emit a test span on startup | `0` |
|
|
491
501
|
| `SECURENOW_HIDE_BANNER` | `1` to suppress free-trial upgrade banner | `0` |
|
|
492
502
|
| `OTEL_LOG_LEVEL` | SDK log level: `none`, `error`, `warn`, `info`, `debug` | `none` |
|
|
493
|
-
| `NODE_ENV` |
|
|
503
|
+
| `SECURENOW_ENVIRONMENT` / `SECURENOW_DEPLOYMENT_ENVIRONMENT` / `NODE_ENV` | Legacy fallback for `config.runtime.deploymentEnvironment` | `production` |
|
|
494
504
|
|
|
495
505
|
### Firewall
|
|
496
506
|
|
|
497
507
|
| Variable | Description | Default |
|
|
498
508
|
|----------|-------------|---------|
|
|
499
|
-
| `SECURENOW_API_KEY` |
|
|
509
|
+
| `SECURENOW_API_KEY` | Legacy env override for the `apiKey` field (`snk_live_...`). Since v7.5.1, login writes the scoped firewall key to `.securenow/credentials.json`. | - |
|
|
500
510
|
| `SECURENOW_API_URL` | SecureNow API base URL | `https://api.securenow.ai` |
|
|
501
511
|
| `SECURENOW_FIREWALL_ENABLED` | Master kill-switch (`0` to disable) | `1` |
|
|
502
512
|
| `SECURENOW_FIREWALL_VERSION_INTERVAL` | Seconds between lightweight version checks | `10` |
|
|
@@ -522,9 +532,9 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
522
532
|
|
|
523
533
|
### Priority Order
|
|
524
534
|
|
|
525
|
-
**Service name:** `
|
|
526
|
-
|
|
527
|
-
**Endpoint:** `
|
|
535
|
+
**Service name:** credentials `app.key` > credentials `app.name` > legacy env fallback > package name
|
|
536
|
+
|
|
537
|
+
**Endpoint:** credentials `config.otel.tracesEndpoint` / `config.otel.endpoint` / `app.instance` > legacy env fallback > `https://freetrial.securenow.ai:4318`
|
|
528
538
|
|
|
529
539
|
---
|
|
530
540
|
|
|
@@ -533,16 +543,11 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
533
543
|
### Add Observability to an Existing Express App
|
|
534
544
|
|
|
535
545
|
```bash
|
|
536
|
-
npm install securenow
|
|
546
|
+
npm install securenow@latest
|
|
547
|
+
npx securenow login
|
|
537
548
|
```
|
|
538
549
|
|
|
539
|
-
|
|
540
|
-
```
|
|
541
|
-
SECURENOW_APPID=my-express-api
|
|
542
|
-
SECURENOW_INSTANCE=https://your-collector:4318
|
|
543
|
-
SECURENOW_LOGGING_ENABLED=1
|
|
544
|
-
SECURENOW_CAPTURE_BODY=1
|
|
545
|
-
```
|
|
550
|
+
No `.env` is needed. `npx securenow login` writes app identity, collector URL, firewall key, and secure defaults to `.securenow/credentials.json`; `npx securenow init` makes sure the file has explanations and is gitignored.
|
|
546
551
|
|
|
547
552
|
Update `package.json`:
|
|
548
553
|
```json
|
|
@@ -554,17 +559,11 @@ No code changes to the application needed.
|
|
|
554
559
|
### Add Observability + Firewall to a Next.js App
|
|
555
560
|
|
|
556
561
|
```bash
|
|
557
|
-
npm install securenow
|
|
562
|
+
npm install securenow@latest
|
|
558
563
|
npx securenow login # pick/create app; firewall key is minted automatically
|
|
559
564
|
```
|
|
560
565
|
|
|
561
|
-
`securenow login` enables the selected app's firewall toggle and writes session, app, and firewall key to `.securenow/credentials.json` (auto-gitignored). Traces, logs, request body capture, multipart metadata capture, and firewall enforcement are enabled by default.
|
|
562
|
-
|
|
563
|
-
```
|
|
564
|
-
SECURENOW_APPID=my-nextjs-app
|
|
565
|
-
SECURENOW_INSTANCE=https://your-collector:4318
|
|
566
|
-
# SECURENOW_API_KEY=snk_live_... (otherwise lives in .securenow/credentials.json)
|
|
567
|
-
```
|
|
566
|
+
`securenow login` enables the selected app's firewall toggle and writes session, app, and firewall key to `.securenow/credentials.json` (auto-gitignored). Traces, logs, request body capture, multipart metadata capture, and firewall enforcement are enabled by default. Then run `npx securenow init`; it creates `instrumentation.ts`, patches `next.config.*` when safe, or prints exact Codex/Claude merge instructions for existing files.
|
|
568
567
|
|
|
569
568
|
### Enable Firewall With Zero Tracing Overhead
|
|
570
569
|
|
|
@@ -574,24 +573,27 @@ For apps that only need IP blocking:
|
|
|
574
573
|
node -r securenow/firewall-only app.js
|
|
575
574
|
```
|
|
576
575
|
|
|
577
|
-
Make sure an API key is resolvable
|
|
576
|
+
Make sure an API key is resolvable by running `npx securenow login` first. If you already have a key, `securenow api-key set snk_live_...` writes the creds file. For production, run `npx securenow credentials runtime --env production` and mount/copy it as `.securenow/credentials.json`.
|
|
578
577
|
|
|
579
|
-
### Production Hardened Configuration
|
|
580
|
-
|
|
581
|
-
```
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
578
|
+
### Production Hardened Configuration
|
|
579
|
+
|
|
580
|
+
```json
|
|
581
|
+
{
|
|
582
|
+
"apiKey": "snk_live_...",
|
|
583
|
+
"app": {
|
|
584
|
+
"key": "prod-api-uuid",
|
|
585
|
+
"name": "prod-api",
|
|
586
|
+
"instance": "https://collector.prod.internal:4318"
|
|
587
|
+
},
|
|
588
|
+
"config": {
|
|
589
|
+
"runtime": { "noUuid": true, "strict": true, "deploymentEnvironment": "production" },
|
|
590
|
+
"logging": { "enabled": true },
|
|
591
|
+
"capture": { "body": true, "multipart": true },
|
|
592
|
+
"firewall": { "enabled": true, "tcp": true, "syncInterval": 30, "failMode": "open" },
|
|
593
|
+
"otel": { "logLevel": "error" }
|
|
594
|
+
}
|
|
595
|
+
}
|
|
596
|
+
```
|
|
595
597
|
|
|
596
598
|
### Instrument a Docker Container
|
|
597
599
|
|
|
@@ -600,25 +602,27 @@ FROM node:20-slim
|
|
|
600
602
|
WORKDIR /app
|
|
601
603
|
COPY package*.json ./
|
|
602
604
|
RUN npm ci --omit=dev
|
|
603
|
-
COPY . .
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
ENV SECURENOW_API_KEY=snk_live_abc123...
|
|
609
|
-
|
|
610
|
-
CMD ["node", "-r", "securenow/register", "src/index.js"]
|
|
611
|
-
```
|
|
605
|
+
COPY . .
|
|
606
|
+
# Mount/copy secret file at runtime as /app/.securenow/credentials.json.
|
|
607
|
+
|
|
608
|
+
CMD ["node", "-r", "securenow/register", "src/index.js"]
|
|
609
|
+
```
|
|
612
610
|
|
|
613
611
|
### Kubernetes with Separate Trace/Log Collectors
|
|
614
612
|
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
613
|
+
```json
|
|
614
|
+
{
|
|
615
|
+
"app": { "key": "k8s-service", "name": "k8s-service" },
|
|
616
|
+
"config": {
|
|
617
|
+
"otel": {
|
|
618
|
+
"tracesEndpoint": "http://tempo:4318/v1/traces",
|
|
619
|
+
"logsEndpoint": "http://loki:4318/v1/logs"
|
|
620
|
+
},
|
|
621
|
+
"logging": { "enabled": true },
|
|
622
|
+
"runtime": { "noUuid": true }
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
```
|
|
622
626
|
|
|
623
627
|
---
|
|
624
628
|
|
|
@@ -626,21 +630,21 @@ SECURENOW_NO_UUID=1
|
|
|
626
630
|
|
|
627
631
|
On startup, securenow logs its configuration:
|
|
628
632
|
|
|
629
|
-
```
|
|
630
|
-
[securenow]
|
|
631
|
-
[securenow] OTel SDK started → https://collector:4318/v1/traces
|
|
632
|
-
[securenow] Logging: ENABLED → https://collector:4318/v1/logs
|
|
633
|
-
[securenow] Request body capture: ENABLED (max: 10240 bytes)
|
|
634
|
-
[securenow] Firewall: ENABLED
|
|
635
|
-
[securenow] Firewall: synced 142 blocked IPs
|
|
636
|
-
```
|
|
637
|
-
|
|
638
|
-
|
|
633
|
+
```
|
|
634
|
+
[securenow] app.key="my-app" → service.name=my-app
|
|
635
|
+
[securenow] OTel SDK started → https://collector:4318/v1/traces
|
|
636
|
+
[securenow] Logging: ENABLED → https://collector:4318/v1/logs
|
|
637
|
+
[securenow] Request body capture: ENABLED (max: 10240 bytes)
|
|
638
|
+
[securenow] Firewall: ENABLED
|
|
639
|
+
[securenow] Firewall: synced 142 blocked IPs
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
Set `config.otel.logLevel` to `debug` in `.securenow/credentials.json` or run `securenow test-span --env <env>` to troubleshoot connectivity issues.
|
|
639
643
|
|
|
640
644
|
**CLI equivalent** (works without booting the SDK — useful when the app won't start):
|
|
641
645
|
|
|
642
|
-
```bash
|
|
643
|
-
securenow env # show resolved
|
|
644
|
-
securenow doctor # probe OTLP + API endpoints, exits 1 on failure
|
|
645
|
-
securenow test-span # send a real span to the collector
|
|
646
|
-
```
|
|
646
|
+
```bash
|
|
647
|
+
securenow env # show resolved app key, endpoints, and credentials fields
|
|
648
|
+
securenow doctor # probe OTLP + API endpoints, exits 1 on failure
|
|
649
|
+
securenow test-span # send a real span to the collector
|
|
650
|
+
```
|