securenow 7.5.1 → 7.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONSUMING-APPS-GUIDE.md +2 -0
- package/NPM_README.md +201 -237
- package/README.md +73 -26
- package/SKILL-API.md +205 -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 +211 -212
- package/cli/monitor.js +107 -43
- package/cli/security.js +24 -12
- package/cli/utils.js +2 -1
- package/cli.js +72 -40
- 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 +22 -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 +48 -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,84 @@ 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
|
+
export async function register() {
|
|
155
|
+
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
156
|
+
|
|
157
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
158
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
159
|
+
registerSecureNow({ captureBody: true });
|
|
160
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
161
|
+
}
|
|
162
|
+
```
|
|
164
163
|
|
|
165
164
|
`registerSecureNow(options?)` accepts:
|
|
166
165
|
|
|
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
|
-
|
|
166
|
+
```typescript
|
|
167
|
+
interface RegisterOptions {
|
|
168
|
+
serviceName?: string; // override credentials app key/name
|
|
169
|
+
endpoint?: string; // override credentials app instance
|
|
170
|
+
noUuid?: boolean; // override credentials config.runtime.noUuid
|
|
171
|
+
captureBody?: boolean; // override credentials config.capture.body
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-node`.
|
|
176
|
+
|
|
177
|
+
**3. Credentials:**
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"app": {
|
|
182
|
+
"key": "<uuid>",
|
|
183
|
+
"name": "my-nextjs-app",
|
|
184
|
+
"instance": "https://freetrial.securenow.ai:4318"
|
|
185
|
+
},
|
|
186
|
+
"config": {
|
|
187
|
+
"logging": { "enabled": true },
|
|
188
|
+
"capture": { "body": true, "multipart": true, "maxBodySize": 10240 },
|
|
189
|
+
"firewall": { "enabled": true }
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
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
195
|
|
|
185
196
|
#### Next.js Body Capture
|
|
186
197
|
|
|
@@ -188,15 +199,16 @@ SECURENOW_INSTANCE=https://your-collector:4318
|
|
|
188
199
|
|
|
189
200
|
Add to your `instrumentation.ts`:
|
|
190
201
|
|
|
191
|
-
```typescript
|
|
192
|
-
export async function register() {
|
|
193
|
-
if (process.env.NEXT_RUNTIME
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
|
|
202
|
+
```typescript
|
|
203
|
+
export async function register() {
|
|
204
|
+
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
|
|
205
|
+
|
|
206
|
+
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
|
|
207
|
+
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
|
|
208
|
+
registerSecureNow({ captureBody: true });
|
|
209
|
+
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
|
|
210
|
+
}
|
|
211
|
+
```
|
|
200
212
|
|
|
201
213
|
**Option B — Middleware:**
|
|
202
214
|
|
|
@@ -219,10 +231,11 @@ export const POST = withSecureNow(async (req) => {
|
|
|
219
231
|
#### Next.js with `securenow init`
|
|
220
232
|
|
|
221
233
|
```bash
|
|
222
|
-
npx securenow
|
|
234
|
+
npx securenow login
|
|
235
|
+
npx securenow init
|
|
223
236
|
```
|
|
224
237
|
|
|
225
|
-
Auto-detects Next.js, creates `instrumentation.ts`,
|
|
238
|
+
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
239
|
|
|
227
240
|
---
|
|
228
241
|
|
|
@@ -232,21 +245,14 @@ Auto-detects Next.js, creates `instrumentation.ts`, suggests `next.config` chang
|
|
|
232
245
|
|
|
233
246
|
```typescript
|
|
234
247
|
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.
|
|
248
|
+
modules: ['securenow/nuxt'],
|
|
249
|
+
securenow: {
|
|
250
|
+
// optional overrides (defaults come from .securenow/credentials.json)
|
|
251
|
+
},
|
|
252
|
+
});
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
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
256
|
|
|
251
257
|
---
|
|
252
258
|
|
|
@@ -267,7 +273,7 @@ Instruments document load, fetch, XMLHttpRequest, and user interactions with bro
|
|
|
267
273
|
|
|
268
274
|
## Firewall — Multi-Layer IP Blocking
|
|
269
275
|
|
|
270
|
-
The firewall auto-activates once an API key is resolvable and the app firewall toggle is on. Since **v7.
|
|
276
|
+
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
277
|
|
|
272
278
|
```
|
|
273
279
|
Layer 4: Cloud/Edge WAF → blocked at CDN (Cloudflare, AWS WAF, GCP Cloud Armor)
|
|
@@ -279,16 +285,13 @@ Layer 1: HTTP Handler → 403 JSON response (always active)
|
|
|
279
285
|
### Activate
|
|
280
286
|
|
|
281
287
|
```bash
|
|
282
|
-
# Zero-config (recommended) — writes the key to .securenow/credentials.json
|
|
283
|
-
npx securenow login # pick/create app; firewall connects automatically
|
|
288
|
+
# Zero-config (recommended) — writes the key to .securenow/credentials.json
|
|
289
|
+
npx securenow login # pick/create app; firewall connects automatically
|
|
284
290
|
# or, if you already have a key:
|
|
285
291
|
npx securenow api-key set snk_live_abc123...
|
|
286
292
|
|
|
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_
|
|
293
|
+
# Production runtime file:
|
|
294
|
+
npx securenow credentials runtime --env production
|
|
292
295
|
```
|
|
293
296
|
|
|
294
297
|
### Firewall-Only Mode (No Tracing Overhead)
|
|
@@ -304,13 +307,14 @@ Loads only dotenv + firewall. No OpenTelemetry, no tracing, no external packages
|
|
|
304
307
|
|
|
305
308
|
### Programmatic Firewall API
|
|
306
309
|
|
|
307
|
-
```javascript
|
|
308
|
-
const firewall = require('securenow/firewall');
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
310
|
+
```javascript
|
|
311
|
+
const firewall = require('securenow/firewall');
|
|
312
|
+
const appConfig = require('securenow/app-config');
|
|
313
|
+
|
|
314
|
+
await firewall.init({
|
|
315
|
+
...appConfig.resolveFirewallOptions(),
|
|
316
|
+
apiUrl: 'https://api.securenow.ai',
|
|
317
|
+
syncInterval: 300, // full sync every 5 min
|
|
314
318
|
versionCheckInterval: 10, // lightweight version check every 10s
|
|
315
319
|
failMode: 'open', // 'open' or 'closed'
|
|
316
320
|
statusCode: 403,
|
|
@@ -440,7 +444,7 @@ const safe = redactSensitiveData({ username: 'alice', password: 's3cret', token:
|
|
|
440
444
|
|
|
441
445
|
**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
446
|
|
|
443
|
-
Add custom fields via `SECURENOW_SENSITIVE_FIELDS=field1,field2
|
|
447
|
+
Add custom fields via `config.capture.sensitiveFields` in `.securenow/credentials.json`; `SECURENOW_SENSITIVE_FIELDS=field1,field2` is a legacy fallback for existing installs.
|
|
444
448
|
|
|
445
449
|
**CLI equivalent** (for piping, scripts, debugging what a payload looks like post-redaction):
|
|
446
450
|
|
|
@@ -451,20 +455,22 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
451
455
|
|
|
452
456
|
---
|
|
453
457
|
|
|
454
|
-
##
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
|
461
|
-
|
|
458
|
+
## Credentials Configuration
|
|
459
|
+
|
|
460
|
+
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.
|
|
461
|
+
|
|
462
|
+
### App Identity
|
|
463
|
+
|
|
464
|
+
| Variable | Description | Default |
|
|
465
|
+
|----------|-------------|---------|
|
|
466
|
+
| `SECURENOW_APPID` | Legacy fallback for `app.key` / service name | from credentials file, then package name |
|
|
467
|
+
| `SECURENOW_INSTANCE` | Legacy fallback for `app.instance` / OTLP collector base URL | from credentials file, then `https://freetrial.securenow.ai:4318` |
|
|
462
468
|
|
|
463
469
|
### Service Naming
|
|
464
470
|
|
|
465
471
|
| Variable | Description | Default |
|
|
466
472
|
|----------|-------------|---------|
|
|
467
|
-
| `OTEL_SERVICE_NAME` |
|
|
473
|
+
| `OTEL_SERVICE_NAME` | Legacy fallback for `app.name` | — |
|
|
468
474
|
| `SECURENOW_NO_UUID` | `1` to use exact app ID without UUID suffix | `0` |
|
|
469
475
|
| `SECURENOW_STRICT` | `1` to exit if APPID missing in PM2 cluster | `0` |
|
|
470
476
|
|
|
@@ -472,9 +478,9 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
472
478
|
|
|
473
479
|
| Variable | Description | Default |
|
|
474
480
|
|----------|-------------|---------|
|
|
475
|
-
| `OTEL_EXPORTER_OTLP_ENDPOINT` |
|
|
476
|
-
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` |
|
|
477
|
-
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` |
|
|
481
|
+
| `OTEL_EXPORTER_OTLP_ENDPOINT` | Legacy fallback for `config.otel.endpoint` | — |
|
|
482
|
+
| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` | Legacy fallback for `config.otel.tracesEndpoint` | `{instance}/v1/traces` |
|
|
483
|
+
| `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | Legacy fallback for `config.otel.logsEndpoint` | `{instance}/v1/logs` |
|
|
478
484
|
| `OTEL_EXPORTER_OTLP_HEADERS` | Comma-separated `key=value` headers for OTLP requests | — |
|
|
479
485
|
|
|
480
486
|
### Behavior
|
|
@@ -482,21 +488,21 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
482
488
|
| Variable | Description | Default |
|
|
483
489
|
|----------|-------------|---------|
|
|
484
490
|
| `SECURENOW_LOGGING_ENABLED` | Enable OTLP log export | `1` |
|
|
485
|
-
| `SECURENOW_CAPTURE_BODY` | Capture HTTP request bodies | `1` |
|
|
491
|
+
| `SECURENOW_CAPTURE_BODY` | Capture HTTP request bodies | `1` |
|
|
486
492
|
| `SECURENOW_MAX_BODY_SIZE` | Max body size in bytes | `10240` |
|
|
487
|
-
| `SECURENOW_CAPTURE_MULTIPART` | Capture multipart/form-data (streaming, metadata only) | `1` |
|
|
493
|
+
| `SECURENOW_CAPTURE_MULTIPART` | Capture multipart/form-data (streaming, metadata only) | `1` |
|
|
488
494
|
| `SECURENOW_SENSITIVE_FIELDS` | Comma-separated extra fields to redact | — |
|
|
489
495
|
| `SECURENOW_DISABLE_INSTRUMENTATIONS` | Comma-separated packages to skip (e.g. `fs,dns`) | — |
|
|
490
496
|
| `SECURENOW_TEST_SPAN` | `1` to emit a test span on startup | `0` |
|
|
491
497
|
| `SECURENOW_HIDE_BANNER` | `1` to suppress free-trial upgrade banner | `0` |
|
|
492
498
|
| `OTEL_LOG_LEVEL` | SDK log level: `none`, `error`, `warn`, `info`, `debug` | `none` |
|
|
493
|
-
| `NODE_ENV` |
|
|
499
|
+
| `SECURENOW_ENVIRONMENT` / `SECURENOW_DEPLOYMENT_ENVIRONMENT` / `NODE_ENV` | Legacy fallback for `config.runtime.deploymentEnvironment` | `production` |
|
|
494
500
|
|
|
495
501
|
### Firewall
|
|
496
502
|
|
|
497
503
|
| Variable | Description | Default |
|
|
498
504
|
|----------|-------------|---------|
|
|
499
|
-
| `SECURENOW_API_KEY` |
|
|
505
|
+
| `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
506
|
| `SECURENOW_API_URL` | SecureNow API base URL | `https://api.securenow.ai` |
|
|
501
507
|
| `SECURENOW_FIREWALL_ENABLED` | Master kill-switch (`0` to disable) | `1` |
|
|
502
508
|
| `SECURENOW_FIREWALL_VERSION_INTERVAL` | Seconds between lightweight version checks | `10` |
|
|
@@ -522,9 +528,9 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
522
528
|
|
|
523
529
|
### Priority Order
|
|
524
530
|
|
|
525
|
-
**Service name:** `
|
|
526
|
-
|
|
527
|
-
**Endpoint:** `
|
|
531
|
+
**Service name:** credentials `app.key` > credentials `app.name` > legacy env fallback > package name
|
|
532
|
+
|
|
533
|
+
**Endpoint:** credentials `config.otel.tracesEndpoint` / `config.otel.endpoint` / `app.instance` > legacy env fallback > `https://freetrial.securenow.ai:4318`
|
|
528
534
|
|
|
529
535
|
---
|
|
530
536
|
|
|
@@ -533,16 +539,11 @@ securenow redact @request.json --fields internal_id,sessionHash
|
|
|
533
539
|
### Add Observability to an Existing Express App
|
|
534
540
|
|
|
535
541
|
```bash
|
|
536
|
-
npm install securenow
|
|
542
|
+
npm install securenow@latest
|
|
543
|
+
npx securenow login
|
|
537
544
|
```
|
|
538
545
|
|
|
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
|
-
```
|
|
546
|
+
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
547
|
|
|
547
548
|
Update `package.json`:
|
|
548
549
|
```json
|
|
@@ -554,17 +555,11 @@ No code changes to the application needed.
|
|
|
554
555
|
### Add Observability + Firewall to a Next.js App
|
|
555
556
|
|
|
556
557
|
```bash
|
|
557
|
-
npm install securenow
|
|
558
|
+
npm install securenow@latest
|
|
558
559
|
npx securenow login # pick/create app; firewall key is minted automatically
|
|
559
560
|
```
|
|
560
561
|
|
|
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
|
-
```
|
|
562
|
+
`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
563
|
|
|
569
564
|
### Enable Firewall With Zero Tracing Overhead
|
|
570
565
|
|
|
@@ -574,24 +569,27 @@ For apps that only need IP blocking:
|
|
|
574
569
|
node -r securenow/firewall-only app.js
|
|
575
570
|
```
|
|
576
571
|
|
|
577
|
-
Make sure an API key is resolvable
|
|
578
|
-
|
|
579
|
-
### Production Hardened Configuration
|
|
572
|
+
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`.
|
|
580
573
|
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
574
|
+
### Production Hardened Configuration
|
|
575
|
+
|
|
576
|
+
```json
|
|
577
|
+
{
|
|
578
|
+
"apiKey": "snk_live_...",
|
|
579
|
+
"app": {
|
|
580
|
+
"key": "prod-api-uuid",
|
|
581
|
+
"name": "prod-api",
|
|
582
|
+
"instance": "https://collector.prod.internal:4318"
|
|
583
|
+
},
|
|
584
|
+
"config": {
|
|
585
|
+
"runtime": { "noUuid": true, "strict": true, "deploymentEnvironment": "production" },
|
|
586
|
+
"logging": { "enabled": true },
|
|
587
|
+
"capture": { "body": true, "multipart": true },
|
|
588
|
+
"firewall": { "enabled": true, "tcp": true, "syncInterval": 30, "failMode": "open" },
|
|
589
|
+
"otel": { "logLevel": "error" }
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
```
|
|
595
593
|
|
|
596
594
|
### Instrument a Docker Container
|
|
597
595
|
|
|
@@ -600,25 +598,27 @@ FROM node:20-slim
|
|
|
600
598
|
WORKDIR /app
|
|
601
599
|
COPY package*.json ./
|
|
602
600
|
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
|
-
```
|
|
601
|
+
COPY . .
|
|
602
|
+
# Mount/copy secret file at runtime as /app/.securenow/credentials.json.
|
|
603
|
+
|
|
604
|
+
CMD ["node", "-r", "securenow/register", "src/index.js"]
|
|
605
|
+
```
|
|
612
606
|
|
|
613
607
|
### Kubernetes with Separate Trace/Log Collectors
|
|
614
608
|
|
|
615
|
-
```
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
609
|
+
```json
|
|
610
|
+
{
|
|
611
|
+
"app": { "key": "k8s-service", "name": "k8s-service" },
|
|
612
|
+
"config": {
|
|
613
|
+
"otel": {
|
|
614
|
+
"tracesEndpoint": "http://tempo:4318/v1/traces",
|
|
615
|
+
"logsEndpoint": "http://loki:4318/v1/logs"
|
|
616
|
+
},
|
|
617
|
+
"logging": { "enabled": true },
|
|
618
|
+
"runtime": { "noUuid": true }
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
```
|
|
622
622
|
|
|
623
623
|
---
|
|
624
624
|
|
|
@@ -626,21 +626,21 @@ SECURENOW_NO_UUID=1
|
|
|
626
626
|
|
|
627
627
|
On startup, securenow logs its configuration:
|
|
628
628
|
|
|
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
|
-
|
|
629
|
+
```
|
|
630
|
+
[securenow] app.key="my-app" → service.name=my-app
|
|
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
|
+
Set `config.otel.logLevel` to `debug` in `.securenow/credentials.json` or run `securenow test-span --env <env>` to troubleshoot connectivity issues.
|
|
639
639
|
|
|
640
640
|
**CLI equivalent** (works without booting the SDK — useful when the app won't start):
|
|
641
641
|
|
|
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
|
-
```
|
|
642
|
+
```bash
|
|
643
|
+
securenow env # show resolved app key, endpoints, and credentials fields
|
|
644
|
+
securenow doctor # probe OTLP + API endpoints, exits 1 on failure
|
|
645
|
+
securenow test-span # send a real span to the collector
|
|
646
|
+
```
|