securenow 8.0.1 → 8.0.3
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/NPM_README.md +31 -30
- package/README.md +13 -7
- package/SKILL-API.md +12 -6
- package/SKILL-CLI.md +8 -7
- package/app-config.js +1 -1
- package/cli/apiKey.js +23 -4
- package/cli/credentials.js +1 -1
- package/cli.js +2 -2
- package/mcp/catalog.js +6 -5
- package/nextjs.js +3 -2
- package/nuxt-server-plugin.mjs +3 -2
- package/otel-defaults.js +30 -2
- package/package.json +1 -1
- package/tracing.js +3 -2
package/NPM_README.md
CHANGED
|
@@ -69,7 +69,7 @@ Run login - it is a browser flow that picks or creates an app and connects the f
|
|
|
69
69
|
npx securenow login
|
|
70
70
|
```
|
|
71
71
|
|
|
72
|
-
During the browser step, the dashboard enables the selected app's firewall toggle, mints
|
|
72
|
+
During the browser step, the dashboard enables the selected app's firewall toggle, mints a one-time plaintext runtime API key scoped to that app only (scopes: `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, `allowlist:read`), and the CLI writes it as `apiKey` in `.securenow/runtime.json`. Admin auth, when part of the flow, is saved separately to `.securenow/admin.json`. Traces, logs, POST body capture, multipart metadata capture, and firewall protection are enabled by default. No env vars, no copy-pasting keys.
|
|
73
73
|
|
|
74
74
|
Metrics export is intentionally off by default. SecureNow sets `OTEL_METRICS_EXPORTER=none` when the app has not explicitly configured metrics, preventing the OpenTelemetry SDK from creating a default metrics reader that retries `localhost:4318`.
|
|
75
75
|
|
|
@@ -77,7 +77,7 @@ For framework scaffolding (Next.js `instrumentation.ts`, `next.config.*`, etc.)
|
|
|
77
77
|
|
|
78
78
|
```bash
|
|
79
79
|
npx securenow init
|
|
80
|
-
# Optional, when you already have a key and did not use browser login:
|
|
80
|
+
# Optional, when you already have a runtime API key and did not use browser login:
|
|
81
81
|
npx securenow init --key snk_live_abc123...
|
|
82
82
|
```
|
|
83
83
|
|
|
@@ -86,13 +86,13 @@ This detects your framework and:
|
|
|
86
86
|
- **Next.js**: Creates `instrumentation.ts`, adds `serverExternalPackages: ['securenow']` plus `outputFileTracingIncludes` when safe, or prints a Codex/Claude-ready merge prompt for existing files
|
|
87
87
|
- **Nuxt 3**: Suggests adding `securenow/nuxt` to modules
|
|
88
88
|
- **Express / Node.js**: Shows how to add `-r securenow/register` to your start script
|
|
89
|
-
- **All**: Stores `--key` in `.securenow/runtime.json`; no local `.env` file is needed
|
|
89
|
+
- **All**: Stores an optional `--key` in `.securenow/runtime.json`; no local `.env` file is needed. If the runtime API key is missing, run `npx securenow app connect` or `npx securenow api-key create` before sending telemetry.
|
|
90
90
|
|
|
91
91
|
### 2. Manual Setup
|
|
92
92
|
|
|
93
93
|
#### Configure Locally
|
|
94
94
|
|
|
95
|
-
Run `npx securenow app connect` to write `.securenow/runtime.json`. The SDK reads app identity, runtime API key, logging/body-capture defaults, and firewall defaults from that file at boot. Telemetry uses the default SecureNow ingestion gateway, routes by `app.key`, and authenticates with the runtime API key, so customer credentials do not expose per-instance collector URLs. Production uses the same file shape via `npx securenow credentials runtime --env production`.
|
|
95
|
+
Run `npx securenow app connect` to write `.securenow/runtime.json`. The SDK reads app identity, runtime API key, logging/body-capture defaults, and firewall defaults from that file at boot. Telemetry uses the default SecureNow ingestion gateway, routes by `app.key`, and authenticates with the runtime API key, so customer credentials do not expose per-instance collector URLs. Production uses the same file shape via `npx securenow credentials runtime --env production`. When rotating later with `npx securenow api-key create`, the CLI defaults to the current app in runtime credentials, resolves its app UUID to the server app id, creates a one-app `runtime_app` key, and stores the plaintext key back into `.securenow/runtime.json`.
|
|
96
96
|
|
|
97
97
|
#### Run Your Application
|
|
98
98
|
|
|
@@ -144,7 +144,7 @@ You'll see confirmation in the console:
|
|
|
144
144
|
|
|
145
145
|
The `securenow` CLI gives you full access to the SecureNow platform from the terminal -- no browser required for day-to-day workflows. Zero additional dependencies.
|
|
146
146
|
|
|
147
|
-
**Full CLI/SDK parity
|
|
147
|
+
**Full CLI/SDK parity:** every SDK export has a matching CLI command. `redactSensitiveData` -> `securenow redact`, `createMatcher` -> `securenow cidr match`, `getLogger().emit()` -> `securenow log send`, startup smoke spans -> `securenow test-span`, `node -r securenow/firewall-only` -> `securenow run --firewall-only`. False-positive triage (`fp create`, `fp ai-fill`, `fp mark`) works from the terminal without the web dashboard.
|
|
148
148
|
|
|
149
149
|
### Getting Started
|
|
150
150
|
|
|
@@ -178,7 +178,7 @@ npx securenow api-key clear # remove just the key
|
|
|
178
178
|
# Auto-detect framework and scaffold instrumentation files
|
|
179
179
|
npx securenow init
|
|
180
180
|
|
|
181
|
-
#
|
|
181
|
+
# Optional: pass an existing runtime API key to store it in .securenow/runtime.json
|
|
182
182
|
npx securenow init --key snk_live_abc123...
|
|
183
183
|
```
|
|
184
184
|
|
|
@@ -505,7 +505,7 @@ npx securenow logs --json --level error | jq '.logs'
|
|
|
505
505
|
| | `apps info <id>` | Application details |
|
|
506
506
|
| | `apps delete <id>` | Delete application |
|
|
507
507
|
| | `apps default <key>` | Set default app |
|
|
508
|
-
| **API Key** | `api-key create [--name "CLI runtime"] [--global]` | Mint and save a
|
|
508
|
+
| **API Key** | `api-key create [--name "CLI runtime"] [--app <key-or-id>] [--global]` | Mint and save a one-app `runtime_app` key with your logged-in session. Defaults to the current runtime app |
|
|
509
509
|
| | `api-key set <snk_live_...> [--global]` | Save runtime API key to `.securenow/runtime.json` |
|
|
510
510
|
| | `api-key show` | Show masked key + source |
|
|
511
511
|
| | `api-key clear [--global]` | Remove stored key (leaves session/app) |
|
|
@@ -623,7 +623,7 @@ module.exports = {
|
|
|
623
623
|
};
|
|
624
624
|
```
|
|
625
625
|
|
|
626
|
-
> **Important:** Put `.securenow/
|
|
626
|
+
> **Important:** Put `.securenow/runtime.json` in the PM2 app root for local/dev deployments, or mount the production runtime export as `.securenow/credentials.json`. Keep `node_args: '-r securenow/register'`. PM2 restarts will then load the SDK, traces/logs, body capture, and firewall without any SecureNow env vars.
|
|
627
627
|
|
|
628
628
|
---
|
|
629
629
|
|
|
@@ -1003,7 +1003,7 @@ const nextConfig = {
|
|
|
1003
1003
|
export default nextConfig;
|
|
1004
1004
|
```
|
|
1005
1005
|
|
|
1006
|
-
No `.env.local` is needed locally or in production.
|
|
1006
|
+
No `.env.local` is needed locally or in production. Local setup reads `.securenow/runtime.json`; production should use `npx securenow credentials runtime --env production` and mount/copy the resulting JSON as `.securenow/credentials.json`.
|
|
1007
1007
|
|
|
1008
1008
|
#### Option B: Manual configuration
|
|
1009
1009
|
|
|
@@ -1050,7 +1050,7 @@ export default defineNuxtConfig({
|
|
|
1050
1050
|
});
|
|
1051
1051
|
```
|
|
1052
1052
|
|
|
1053
|
-
Local
|
|
1053
|
+
Local app identity, runtime API key, and secure defaults come from `.securenow/runtime.json`; production can mount the generated tokenless runtime file as `.securenow/credentials.json` or `.securenow/credentials.<env>.json`.
|
|
1054
1054
|
|
|
1055
1055
|
That's it -- the Nuxt module handles OTel SDK initialization, Nitro externalization, firewall activation, and request tracing automatically. Optional config:
|
|
1056
1056
|
|
|
@@ -1097,18 +1097,18 @@ SecureNow can automatically block IPs from your blocklist at the application lay
|
|
|
1097
1097
|
Pick whichever fits your environment:
|
|
1098
1098
|
|
|
1099
1099
|
```bash
|
|
1100
|
-
# (a) Zero-config (
|
|
1101
|
-
#
|
|
1100
|
+
# (a) Zero-config (v8+): login picks/creates an app and connects the firewall.
|
|
1101
|
+
# Runtime API key is minted and written to .securenow/runtime.json automatically.
|
|
1102
1102
|
npx securenow login
|
|
1103
1103
|
|
|
1104
|
-
# (b) Already have a key? Write it to
|
|
1104
|
+
# (b) Already have a runtime API key? Write it to runtime credentials directly:
|
|
1105
1105
|
npx securenow api-key set snk_live_abc123...
|
|
1106
1106
|
|
|
1107
1107
|
# (c) Production? Generate a tokenless runtime credentials file:
|
|
1108
1108
|
npx securenow credentials runtime --env production
|
|
1109
1109
|
```
|
|
1110
1110
|
|
|
1111
|
-
The SDK resolves the runtime API key from project `./.securenow/
|
|
1111
|
+
The SDK resolves the runtime API key from project `./.securenow/runtime.json`, legacy project `./.securenow/credentials.json`, project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order, global `~/.securenow/runtime.json`, legacy global credentials, then global named runtime credentials in the same fixed order.
|
|
1112
1112
|
|
|
1113
1113
|
On startup, you'll see:
|
|
1114
1114
|
|
|
@@ -1139,7 +1139,7 @@ If you only need IP blocking without OpenTelemetry tracing overhead, use the sta
|
|
|
1139
1139
|
# Manual preload flag
|
|
1140
1140
|
node -r securenow/firewall-only app.js
|
|
1141
1141
|
|
|
1142
|
-
# Or via the CLI
|
|
1142
|
+
# Or via the CLI - same effect, clearer intent
|
|
1143
1143
|
securenow run --firewall-only app.js
|
|
1144
1144
|
```
|
|
1145
1145
|
|
|
@@ -1157,7 +1157,7 @@ This is useful when:
|
|
|
1157
1157
|
- You're adding the firewall to a project that uses a different tracing solution
|
|
1158
1158
|
- For non-Next Node apps, this avoids framework-specific tracing setup entirely
|
|
1159
1159
|
|
|
1160
|
-
Firewall-only mode uses the same
|
|
1160
|
+
Firewall-only mode uses the same runtime API key written by `login`, `app connect`, `api-key create`, `api-key set`, or mounted from a runtime credentials file:
|
|
1161
1161
|
|
|
1162
1162
|
```bash
|
|
1163
1163
|
npx securenow credentials runtime --env production
|
|
@@ -1197,9 +1197,9 @@ Use `npx securenow firewall status`, `npx securenow firewall apps`, and `npx sec
|
|
|
1197
1197
|
|
|
1198
1198
|
## Credentials Configuration
|
|
1199
1199
|
|
|
1200
|
-
Local development
|
|
1200
|
+
Local development uses `.securenow/runtime.json`. Run `npx securenow login` or `npx securenow app connect`, then `npx securenow init`; for production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json` or `.securenow/credentials.<env>.json`.
|
|
1201
1201
|
|
|
1202
|
-
Use `.securenow/
|
|
1202
|
+
Use `.securenow/runtime.json` as the local source of truth. Run `npx securenow env --json` to inspect resolved settings without exposing secrets.
|
|
1203
1203
|
|
|
1204
1204
|
### Credentials Fields
|
|
1205
1205
|
|
|
@@ -1207,7 +1207,7 @@ Use `.securenow/credentials.json` as the source of truth. Run `npx securenow env
|
|
|
1207
1207
|
|----------|-------------|---------|
|
|
1208
1208
|
| `app.key` | App routing UUID. The SecureNow ingestion gateway routes telemetry by this key. | selected during login |
|
|
1209
1209
|
| `app.name` | Human-readable app label. | selected during login |
|
|
1210
|
-
| `apiKey` |
|
|
1210
|
+
| `apiKey` | One-app scoped runtime API key (`snk_live_...`) for telemetry ingestion and firewall sync. Runtime scopes are `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, and `allowlist:read`. | minted during login |
|
|
1211
1211
|
| `config.runtime.deploymentEnvironment` | `deployment.environment` trace/log scope. | `local` from init, `production` from runtime credentials |
|
|
1212
1212
|
| `config.logging.enabled` | Automatic console log export. | `true` |
|
|
1213
1213
|
| `config.capture.body` | Request body capture with redaction. | `true` |
|
|
@@ -1223,7 +1223,8 @@ Environment-variable fallback is not supported.
|
|
|
1223
1223
|
**Default sensitive fields (auto-redacted):** `password`, `passwd`, `pwd`, `secret`, `token`, `api_key`, `apikey`, `access_token`, `auth`, `credentials`, `mysql_pwd`, `stripeToken`, `card`, `cardnumber`, `ccv`, `cvc`, `cvv`, `ssn`, `pin`
|
|
1224
1224
|
|
|
1225
1225
|
For instrumentation, firewall layers, debugging, trusted proxies, and deployment
|
|
1226
|
-
environment, edit the matching `config.*` keys in `.securenow/
|
|
1226
|
+
environment, edit the matching `config.*` keys in `.securenow/runtime.json`
|
|
1227
|
+
locally or in the mounted production runtime credentials file.
|
|
1227
1228
|
Use `npx securenow env --json` to inspect the resolved values and
|
|
1228
1229
|
`npx securenow help firewall` for the firewall command reference.
|
|
1229
1230
|
|
|
@@ -1273,7 +1274,7 @@ console.debug('Debug info');
|
|
|
1273
1274
|
- `console.error()` -> ERROR
|
|
1274
1275
|
- `console.debug()` -> DEBUG
|
|
1275
1276
|
|
|
1276
|
-
Logging is controlled by `config.logging.enabled` in `.securenow/credentials.
|
|
1277
|
+
Logging is controlled by `config.logging.enabled` in `.securenow/runtime.json` locally or the mounted production runtime credentials file.
|
|
1277
1278
|
|
|
1278
1279
|
### Direct Logger API
|
|
1279
1280
|
|
|
@@ -1316,7 +1317,7 @@ node -r securenow/register app.js
|
|
|
1316
1317
|
|
|
1317
1318
|
## Request Body Capture
|
|
1318
1319
|
|
|
1319
|
-
SecureNow captures HTTP request bodies in traces by default, with sensitive fields automatically redacted. Set `config.capture.body=false` in `.securenow/
|
|
1320
|
+
SecureNow captures HTTP request bodies in traces by default, with sensitive fields automatically redacted. Set `config.capture.body=false` in `.securenow/runtime.json` locally or the mounted production runtime credentials file only when you need an opt-out.
|
|
1320
1321
|
|
|
1321
1322
|
### Body Capture Defaults
|
|
1322
1323
|
|
|
@@ -1470,10 +1471,10 @@ if (isLoggingEnabled()) {
|
|
|
1470
1471
|
|
|
1471
1472
|
### Programmatic Configuration
|
|
1472
1473
|
|
|
1473
|
-
Use `.securenow/
|
|
1474
|
+
Use `.securenow/runtime.json` for local development and tests; CI/production should mount the generated runtime credentials file:
|
|
1474
1475
|
|
|
1475
1476
|
```javascript
|
|
1476
|
-
// Reads .securenow/
|
|
1477
|
+
// Reads .securenow/runtime.json first, with legacy/generated runtime credentials as fallbacks.
|
|
1477
1478
|
require('securenow/register');
|
|
1478
1479
|
```
|
|
1479
1480
|
|
|
@@ -1565,7 +1566,7 @@ npx securenow env
|
|
|
1565
1566
|
npx securenow status --env local
|
|
1566
1567
|
```
|
|
1567
1568
|
|
|
1568
|
-
The output should show an app key, collector endpoint, and deployment environment from `.securenow/credentials.
|
|
1569
|
+
The output should show an app key, runtime API key source, collector endpoint, and deployment environment from `.securenow/runtime.json` or the mounted runtime credentials file.
|
|
1569
1570
|
|
|
1570
1571
|
**Check 2: Verify OTLP collector is running**
|
|
1571
1572
|
|
|
@@ -1614,7 +1615,7 @@ require('securenow/register');
|
|
|
1614
1615
|
|
|
1615
1616
|
### Firewall Not Blocking IPs
|
|
1616
1617
|
|
|
1617
|
-
**Check 1: Is
|
|
1618
|
+
**Check 1: Is a runtime API key in `.securenow/runtime.json` or the mounted runtime credentials file?**
|
|
1618
1619
|
|
|
1619
1620
|
```bash
|
|
1620
1621
|
npx securenow api-key show
|
|
@@ -1651,7 +1652,7 @@ proxy_set_header X-Real-IP $remote_addr;
|
|
|
1651
1652
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|
1652
1653
|
```
|
|
1653
1654
|
|
|
1654
|
-
SecureNow trusts private, loopback, and same-host proxy peers automatically. For external load balancers or public proxy IPs, add them to `config.networking.trustedProxies` in `.securenow/
|
|
1655
|
+
SecureNow trusts private, loopback, and same-host proxy peers automatically. For external load balancers or public proxy IPs, add them to `config.networking.trustedProxies` in `.securenow/runtime.json` or the mounted runtime credentials file. If no forwarded header reaches the app, SecureNow can detect the attack shape but cannot recover the real visitor IP from traces.
|
|
1655
1656
|
|
|
1656
1657
|
**Check 6: Using PM2?**
|
|
1657
1658
|
|
|
@@ -1822,14 +1823,14 @@ Without `node_args`, PM2 starts your script directly without the securenow prelo
|
|
|
1822
1823
|
|
|
1823
1824
|
### 1. Use the Credentials File
|
|
1824
1825
|
|
|
1825
|
-
Do not hardcode configuration in code or deployment dashboards. Use `.securenow/
|
|
1826
|
+
Do not hardcode configuration in code or deployment dashboards. Use `.securenow/runtime.json` locally and mount the tokenless runtime file in production:
|
|
1826
1827
|
|
|
1827
1828
|
```javascript
|
|
1828
1829
|
// Bad
|
|
1829
1830
|
const appKey = 'hardcoded-value';
|
|
1830
1831
|
|
|
1831
|
-
// Good: use .securenow/
|
|
1832
|
-
// { "app": { "key": "
|
|
1832
|
+
// Good: use .securenow/runtime.json
|
|
1833
|
+
// { "app": { "key": "<uuid>", "instance": "https://ingest.securenow.ai" }, "apiKey": "snk_live_..." }
|
|
1833
1834
|
```
|
|
1834
1835
|
|
|
1835
1836
|
### 2. Use Structured Logging
|
package/README.md
CHANGED
|
@@ -37,7 +37,13 @@ That's it. No `.env` edits, no API keys to paste, no peer-dep warnings. Your tra
|
|
|
37
37
|
`npx securenow login` opens a browser and runs both lanes for onboarding:
|
|
38
38
|
|
|
39
39
|
- admin/control-plane CLI and MCP auth goes to `.securenow/admin.json`
|
|
40
|
-
- app/runtime SDK config and the
|
|
40
|
+
- app/runtime SDK config and the runtime API key go to `.securenow/runtime.json`
|
|
41
|
+
|
|
42
|
+
During app runtime onboarding, the browser flow returns a one-time plaintext
|
|
43
|
+
`snk_live_...` key scoped to the selected app only. The CLI writes that key as
|
|
44
|
+
`apiKey` in `.securenow/runtime.json`. Its `runtime_app` scopes are
|
|
45
|
+
`traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, and
|
|
46
|
+
`allowlist:read`.
|
|
41
47
|
|
|
42
48
|
Use `npx securenow admin login` to refresh only admin auth, or `npx securenow app connect` to refresh only runtime app config. Legacy combined `.securenow/credentials.json` files are still read for old installs.
|
|
43
49
|
|
|
@@ -60,7 +66,7 @@ Runtime credentials look like:
|
|
|
60
66
|
}
|
|
61
67
|
```
|
|
62
68
|
|
|
63
|
-
The SDK reads the runtime file at boot
|
|
69
|
+
The SDK reads the runtime file at boot, sends traces/logs through the SecureNow ingest gateway, routes by `app.key`, and authenticates with the runtime API key. When you rotate with `npx securenow api-key create`, the CLI defaults to the current app in `.securenow/runtime.json`, resolves that app UUID to the server app id, creates a one-app `runtime_app` key, and stores the plaintext key back into runtime credentials. `npx securenow init` also fills the config block with secure defaults plus an `_securenow.explanations` section so users can see what every setting does.
|
|
64
70
|
|
|
65
71
|
---
|
|
66
72
|
|
|
@@ -75,7 +81,7 @@ npx securenow login
|
|
|
75
81
|
Then ask your coding agent to wire each app with this prompt:
|
|
76
82
|
|
|
77
83
|
```text
|
|
78
|
-
I already ran npx securenow login from the repo root. For every Node.js or Next.js app under this repo: install securenow@latest, run or merge npx securenow init, create or reuse a SecureNow app, write local .securenow/runtime.json plus tokenless .securenow/credentials.production.json
|
|
84
|
+
I already ran npx securenow login from the repo root. For every Node.js or Next.js app under this repo: install securenow@latest, run or merge npx securenow init, create or reuse a SecureNow app, write local .securenow/runtime.json plus tokenless .securenow/credentials.production.json for secret-file deployment, enable traces, logs, body capture, multipart metadata, and firewall, then verify with npx securenow env --json, npx securenow test-span, npx securenow log send, and a local HTTP smoke test where possible. Do not print secrets.
|
|
79
85
|
```
|
|
80
86
|
|
|
81
87
|
For production, deploy the tokenless runtime credentials as a secret file mounted at `<app-root>/.securenow/credentials.json`.
|
|
@@ -163,7 +169,7 @@ SecureNow does not export metrics by default. The preload sets `OTEL_METRICS_EXP
|
|
|
163
169
|
|
|
164
170
|
## Production Without Env Vars
|
|
165
171
|
|
|
166
|
-
Production uses the same file structure.
|
|
172
|
+
Production uses the same file structure. Deploy a tokenless runtime credentials file as a secret file and mount/copy it to:
|
|
167
173
|
|
|
168
174
|
```text
|
|
169
175
|
<app-root>/.securenow/credentials.json
|
|
@@ -177,7 +183,7 @@ npx securenow credentials runtime --env production
|
|
|
177
183
|
|
|
178
184
|
It writes `.securenow/credentials.production.json`, with the same `app`, `apiKey`, `config`, and `_securenow.explanations` shape, but without the CLI OAuth `token`, `email`, or `expiresAt`. Store that JSON in your deployment secret manager and materialize it as `.securenow/credentials.json` at runtime.
|
|
179
185
|
|
|
180
|
-
|
|
186
|
+
The v8 SDK also accepts generated runtime filenames directly without reading environment variables to choose the file. If `.securenow/credentials.json` is missing, it checks named files in a deterministic order: staging, production, preview, local, test, development, dev, then prod.
|
|
181
187
|
|
|
182
188
|
Resolution order:
|
|
183
189
|
|
|
@@ -258,7 +264,7 @@ Use `.securenow/runtime.json` fields for new local SDK/runtime setups. Productio
|
|
|
258
264
|
|---|---|---|
|
|
259
265
|
| `app.key` | selected during login | App routing UUID; the gateway routes telemetry by this key |
|
|
260
266
|
| `app.name` | selected during login | Human-readable label for CLI and dashboard output |
|
|
261
|
-
| `apiKey` | minted during login |
|
|
267
|
+
| `apiKey` | minted during login | One-app scoped runtime API key (`snk_live_...`) for telemetry ingestion and firewall sync. Runtime scopes: `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, `allowlist:read` |
|
|
262
268
|
| `config.runtime.deploymentEnvironment` | `local` from `init`, `production` from runtime credentials | Sent as OTel `deployment.environment` |
|
|
263
269
|
| `config.logging.enabled` | `true` | Forward `console.*` as OTLP logs |
|
|
264
270
|
| `config.capture.body` | `true` | Capture JSON / form request bodies with redaction |
|
|
@@ -330,7 +336,7 @@ After install, the `securenow` CLI is available via `npx securenow` or globally
|
|
|
330
336
|
| `securenow logout` | Clear admin auth only; runtime app config stays intact |
|
|
331
337
|
| `securenow logout --global` | Clear ~/.securenow/ instead |
|
|
332
338
|
| `securenow whoami` | Show admin auth and runtime app status separately |
|
|
333
|
-
| `securenow api-key create [--name "CLI runtime"]` | Mint and store a
|
|
339
|
+
| `securenow api-key create [--name "CLI runtime"] [--app <key-or-id>]` | Mint and store a one-app `runtime_app` key. Defaults to the current app in `.securenow/runtime.json` |
|
|
334
340
|
| `securenow api-key set <snk_live_...>` | Store runtime API key in `.securenow/runtime.json` (`--global` for `~/.securenow/`) |
|
|
335
341
|
| `securenow api-key show` | Print masked key + source file |
|
|
336
342
|
| `securenow api-key clear` | Remove stored key (`--global` for `~/.securenow/`) |
|
package/SKILL-API.md
CHANGED
|
@@ -32,7 +32,7 @@ npx securenow app connect # SDK runtime app + runtime API key only
|
|
|
32
32
|
npx securenow init
|
|
33
33
|
```
|
|
34
34
|
|
|
35
|
-
Use `securenow@
|
|
35
|
+
Use `securenow@8.0.0` or newer for split admin/runtime credentials and runtime-authenticated ingestion. Start authentication with `npx securenow login`; do not manually open auth URLs, because the CLI generates the callback/state values. The friendly login flow can connect both lanes, while `npx securenow admin login` only writes `.securenow/admin.json` and `npx securenow app connect` only writes `.securenow/runtime.json`. `init` scaffolds the framework integration.
|
|
36
36
|
|
|
37
37
|
### 2. Run With Instrumentation
|
|
38
38
|
|
|
@@ -70,7 +70,13 @@ npx securenow app connect # pick/create app; runtime API key is minted au
|
|
|
70
70
|
npx securenow api-key set snk_live_abc123...
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
Both paths write the key to `.securenow/runtime.json`
|
|
73
|
+
Both paths write the key to `.securenow/runtime.json` 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` or `.securenow/credentials.<env>.json`.
|
|
74
|
+
|
|
75
|
+
The automatically created key is scoped to the selected app only. Its
|
|
76
|
+
`runtime_app` scopes are `traces:write`, `logs:write`, `firewall:read`,
|
|
77
|
+
`blocklist:read`, and `allowlist:read`. `securenow api-key create` uses the
|
|
78
|
+
current app from `.securenow/runtime.json` by default, resolves that app UUID to
|
|
79
|
+
the server app id, and stores the new one-time plaintext key back as `apiKey`.
|
|
74
80
|
|
|
75
81
|
The firewall syncs your blocklist and enforces it on every request — zero code changes.
|
|
76
82
|
|
|
@@ -218,7 +224,7 @@ On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-n
|
|
|
218
224
|
}
|
|
219
225
|
```
|
|
220
226
|
|
|
221
|
-
Local development and production do not need `.env.local`; `npx securenow app connect` and `npx securenow init` keep `.securenow/runtime.json` filled and
|
|
227
|
+
Local development and production do not need `.env.local`; `npx securenow app connect` and `npx securenow init` keep `.securenow/runtime.json` filled with runtime credentials and secure defaults. For production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json` or `.securenow/credentials.production.json`.
|
|
222
228
|
|
|
223
229
|
#### Next.js Body Capture
|
|
224
230
|
|
|
@@ -543,7 +549,7 @@ Local development uses `.securenow/runtime.json`; legacy `.securenow/credentials
|
|
|
543
549
|
|---|---|
|
|
544
550
|
| `app.key` | App routing UUID. The SecureNow ingestion gateway routes telemetry by this key |
|
|
545
551
|
| `app.name` | Human-readable app label |
|
|
546
|
-
| `apiKey` |
|
|
552
|
+
| `apiKey` | One-app scoped runtime API key (`snk_live_...`) for telemetry ingestion and firewall sync. Runtime scopes: `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, `allowlist:read` |
|
|
547
553
|
| `config.otel.endpoint` | Optional OTLP base endpoint override |
|
|
548
554
|
| `config.otel.tracesEndpoint` | Optional full traces endpoint |
|
|
549
555
|
| `config.otel.logsEndpoint` | Optional full logs endpoint |
|
|
@@ -589,7 +595,7 @@ npm install securenow@latest
|
|
|
589
595
|
npx securenow login
|
|
590
596
|
```
|
|
591
597
|
|
|
592
|
-
No `.env` is needed. `npx securenow app connect` writes app identity, runtime API key, and secure defaults to `.securenow/runtime.json`; the SDK uses the default SecureNow ingestion gateway and the gateway routes by `app.key` while authenticating with the runtime API key. `npx securenow init` makes sure the file has explanations and
|
|
598
|
+
No `.env` is needed. `npx securenow app connect` writes app identity, runtime API key, and secure defaults to `.securenow/runtime.json`; the SDK uses the default SecureNow ingestion gateway and the gateway routes by `app.key` while authenticating with the runtime API key. `npx securenow init` makes sure the file has explanations and secure SDK defaults.
|
|
593
599
|
|
|
594
600
|
Update `package.json`:
|
|
595
601
|
```json
|
|
@@ -605,7 +611,7 @@ npm install securenow@latest
|
|
|
605
611
|
npx securenow app connect # pick/create app; runtime API key is minted automatically
|
|
606
612
|
```
|
|
607
613
|
|
|
608
|
-
`securenow app connect` enables the selected app's firewall toggle and writes app/runtime config plus the runtime API key to `.securenow/runtime.json
|
|
614
|
+
`securenow app connect` enables the selected app's firewall toggle and writes app/runtime config plus the runtime API key to `.securenow/runtime.json`. 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.
|
|
609
615
|
|
|
610
616
|
### Enable Firewall With Zero Tracing Overhead
|
|
611
617
|
|
package/SKILL-CLI.md
CHANGED
|
@@ -15,7 +15,7 @@ npx securenow <command>
|
|
|
15
15
|
|
|
16
16
|
**Full parity with the SDK:** every capability the `securenow` Node SDK exposes has a CLI counterpart — redaction, CIDR matching, log/span emission, firewall preload, config inspection. If you can do it in code, you can do it from the terminal.
|
|
17
17
|
|
|
18
|
-
**MCP parity (
|
|
18
|
+
**MCP parity (v8.0+):** the same package also ships a local stdio MCP server for Codex, Claude, and other MCP clients:
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
npx securenow login
|
|
@@ -40,11 +40,11 @@ securenow whoami # verify both admin auth and runtime app status
|
|
|
40
40
|
|
|
41
41
|
**Zero-config runtime flow:** the browser step lets the user pick (or create) an app. The CLI stores the app's **key (UUID)** and **name** in `.securenow/runtime.json`. The SDK sends traces/logs to the default SecureNow ingestion gateway, which routes by app key, so no env vars or per-instance collector URLs are required for local dev or production.
|
|
42
42
|
|
|
43
|
-
**Default-on security (
|
|
43
|
+
**Default-on security (v8.0+):** after picking or creating the app, `securenow app connect` turns on that app's firewall toggle, mints a runtime API key with `traces:write + logs:write + firewall:read + blocklist:read + allowlist:read` scopes, and writes it into `.securenow/runtime.json`. Traces, logs, POST body capture, multipart metadata capture, and the firewall are enabled by default. No `SECURENOW_API_KEY` env var is needed. To add or rotate a key later without re-running app connect, use `securenow api-key create` or `securenow api-key set snk_live_...` (see [API Key Management](#api-key-management) below).
|
|
44
44
|
|
|
45
45
|
Runtime credentials resolve in order: project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Runtime config is credentials-json based; environment-variable fallbacks are not supported.
|
|
46
46
|
|
|
47
|
-
The **
|
|
47
|
+
The **runtime API key** should live in runtime credentials as `apiKey`; it authenticates telemetry ingestion and firewall sync.
|
|
48
48
|
|
|
49
49
|
For CI / Docker / production, use `securenow credentials runtime --env production` to generate a tokenless runtime file, then mount/copy it as `.securenow/credentials.json`. Since v7.7.2, mounting the generated `.securenow/credentials.production.json` filename directly also works when `credentials.json` is absent.
|
|
50
50
|
|
|
@@ -161,7 +161,8 @@ securenow apps scan [--yes] # scan all app domains for new subd
|
|
|
161
161
|
Manage the runtime API key stored in runtime credentials. Since v8.0 the app runtime flow writes app-scoped `snk_live_...` keys to `.securenow/runtime.json` by default, so no env var is required for local dev.
|
|
162
162
|
|
|
163
163
|
```bash
|
|
164
|
-
securenow api-key create --name "CLI runtime" # mint + save a runtime
|
|
164
|
+
securenow api-key create --name "CLI runtime" # mint + save a current-app runtime key
|
|
165
|
+
securenow api-key create --app <key-or-id> # mint + save a runtime key scoped to another app
|
|
165
166
|
securenow api-key set snk_live_xxxxxxxxxx # save to project ./.securenow/ (default)
|
|
166
167
|
securenow api-key set snk_live_xxx --global # save to ~/.securenow/ instead
|
|
167
168
|
securenow api-key show # print the masked current key + its source
|
|
@@ -170,7 +171,7 @@ securenow api-key clear --global # same, but from the global file
|
|
|
170
171
|
securenow credentials runtime --env production # write .securenow/credentials.production.json for production secret-file deploys
|
|
171
172
|
```
|
|
172
173
|
|
|
173
|
-
The key must start with `snk_live_`. `securenow app connect` writes the key automatically; use `api-key create` when you have admin auth but no runtime key yet, or `api-key set` when you already have a key from the dashboard.
|
|
174
|
+
The key must start with `snk_live_`. `securenow app connect` writes the key automatically; use `api-key create` when you have admin auth but no runtime key yet, or `api-key set` when you already have a key from the dashboard. `api-key create` defaults to the current app in `.securenow/runtime.json`, resolves that app UUID to the server app id, creates a one-app `runtime_app` key with `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, and `allowlist:read`, then stores the one-time plaintext key as `apiKey`.
|
|
174
175
|
|
|
175
176
|
### Init — Project Setup
|
|
176
177
|
|
|
@@ -179,7 +180,7 @@ securenow init [--env local] [--key <API_KEY>]
|
|
|
179
180
|
```
|
|
180
181
|
|
|
181
182
|
Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
|
|
182
|
-
- **Credentials**: ensures `.securenow/runtime.json` exists
|
|
183
|
+
- **Credentials**: ensures `.securenow/runtime.json` exists with secure defaults and explanations
|
|
183
184
|
- **Next.js**: creates `instrumentation.ts/js` with `securenow/nextjs` + `securenow/nextjs-auto-capture`, and adds `serverExternalPackages: ['securenow']` plus `outputFileTracingIncludes` when the config can be patched safely
|
|
184
185
|
- **Existing Next.js files**: prints a Codex/Claude-ready merge prompt when instrumentation or config already exists or is too custom to safely patch
|
|
185
186
|
- **Nuxt**: tells you to add `securenow/nuxt` to modules
|
|
@@ -313,7 +314,7 @@ securenow firewall status --app <key> --env production # app/env toggle, sync
|
|
|
313
314
|
securenow firewall test-ip <ip> --app <key> --env local # check if IP would be blocked
|
|
314
315
|
```
|
|
315
316
|
|
|
316
|
-
**Zero-config setup:** running `securenow app connect` enables the selected app's firewall toggle, auto-mints
|
|
317
|
+
**Zero-config setup:** running `securenow app connect` enables the selected app's firewall toggle, auto-mints a runtime API key (scoped `traces:write + logs:write + firewall:read + blocklist:read + allowlist:read`), and writes it to `.securenow/runtime.json` after the app is selected. No `SECURENOW_API_KEY` env var needed. If the user already has a key, `securenow api-key set snk_live_...` achieves the same thing; if they only have admin auth, `securenow api-key create` mints and saves a fresh runtime key. See [the landing firewall page](https://securenow.ai/firewall) for an overview.
|
|
317
318
|
|
|
318
319
|
### Blocklist — Block Malicious IPs
|
|
319
320
|
|
package/app-config.js
CHANGED
|
@@ -419,7 +419,7 @@ function withCredentialDefaults(credentials) {
|
|
|
419
419
|
out.config = mergeMissing(out.config, DEFAULT_CONFIG);
|
|
420
420
|
out._securenow = mergeMissing(out._securenow, {
|
|
421
421
|
schemaVersion: CONFIG_SCHEMA_VERSION,
|
|
422
|
-
note: 'Local SecureNow credentials and secure SDK defaults. This file may contain secrets
|
|
422
|
+
note: 'Local SecureNow credentials and secure SDK defaults. This file may contain secrets.',
|
|
423
423
|
precedence: 'The same credentials file works in local development and production. SDK runtime config is read from credentials JSON only.',
|
|
424
424
|
explanations: CONFIG_EXPLANATIONS,
|
|
425
425
|
});
|
package/cli/apiKey.js
CHANGED
|
@@ -8,11 +8,31 @@ const PRESET_SCOPES = {
|
|
|
8
8
|
runtime_app: ['traces:write', 'logs:write', 'firewall:read', 'blocklist:read', 'allowlist:read'],
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
const OBJECT_ID_RE = /^[a-f0-9]{24}$/i;
|
|
12
|
+
|
|
11
13
|
function maskKey(key) {
|
|
12
14
|
if (!key || key.length < 16) return key || '';
|
|
13
15
|
return `${key.slice(0, 12)}••••••${key.slice(-4)}`;
|
|
14
16
|
}
|
|
15
17
|
|
|
18
|
+
async function resolveAppScopeForApi(appIdentifier) {
|
|
19
|
+
const raw = String(appIdentifier || '').trim();
|
|
20
|
+
if (!raw || OBJECT_ID_RE.test(raw)) return raw || null;
|
|
21
|
+
|
|
22
|
+
const data = await api.get('/applications');
|
|
23
|
+
const app = (data.applications || []).find((candidate) =>
|
|
24
|
+
candidate.key === raw ||
|
|
25
|
+
candidate._id === raw ||
|
|
26
|
+
candidate.id === raw
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
if (!app) {
|
|
30
|
+
throw new Error(`Could not find application for --app ${raw}`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return app._id || app.id || raw;
|
|
34
|
+
}
|
|
35
|
+
|
|
16
36
|
async function create(args, flags) {
|
|
17
37
|
requireAuth();
|
|
18
38
|
|
|
@@ -27,10 +47,9 @@ async function create(args, flags) {
|
|
|
27
47
|
if (PRESET_SCOPES[preset]) {
|
|
28
48
|
body.scopes = PRESET_SCOPES[preset];
|
|
29
49
|
}
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
body.apps = [app.key];
|
|
50
|
+
const appScope = flags.app || (preset === 'runtime_app' && app?.key ? app.key : null);
|
|
51
|
+
if (appScope) {
|
|
52
|
+
body.apps = [await resolveAppScopeForApi(appScope)];
|
|
34
53
|
}
|
|
35
54
|
|
|
36
55
|
const result = await api.post('/api-keys', body);
|
package/cli/credentials.js
CHANGED
|
@@ -39,7 +39,7 @@ function buildRuntimeCredentials(options = {}) {
|
|
|
39
39
|
},
|
|
40
40
|
_securenow: {
|
|
41
41
|
...(creds._securenow || {}),
|
|
42
|
-
note: 'Runtime SecureNow credentials and SDK defaults. Mount or copy this JSON as .securenow/credentials.json or .securenow/credentials.<environment>.json in production.
|
|
42
|
+
note: 'Runtime SecureNow credentials and SDK defaults. Mount or copy this JSON as .securenow/credentials.json or .securenow/credentials.<environment>.json in production.',
|
|
43
43
|
routing: 'Telemetry is sent to the default SecureNow ingestion gateway. The gateway routes by app.key, so runtime credentials do not expose per-instance collector URLs.',
|
|
44
44
|
runtimeOnly: 'This file intentionally omits CLI OAuth fields: token, email, and expiresAt.',
|
|
45
45
|
production: 'Production can use this same file shape instead of environment variables.',
|
package/cli.js
CHANGED
|
@@ -116,11 +116,11 @@ const COMMANDS = {
|
|
|
116
116
|
sub: {
|
|
117
117
|
create: {
|
|
118
118
|
desc: 'Create a runtime API key with your session token and save it',
|
|
119
|
-
usage: 'securenow api-key create [name] [--name <name>] [--preset runtime_app] [--app <
|
|
119
|
+
usage: 'securenow api-key create [name] [--name <name>] [--preset runtime_app] [--app <appKeyOrId>] [--global]',
|
|
120
120
|
flags: {
|
|
121
121
|
name: 'Human-readable key name',
|
|
122
122
|
preset: 'API key preset to create (default: runtime_app)',
|
|
123
|
-
app: 'Application key
|
|
123
|
+
app: 'Application key or id to scope this key to (defaults to current runtime app)',
|
|
124
124
|
global: 'Save to ~/.securenow/ instead of project-local',
|
|
125
125
|
},
|
|
126
126
|
run: (a, f) => require('./cli/apiKey').create(a, f),
|
package/mcp/catalog.js
CHANGED
|
@@ -10,7 +10,7 @@ const MARKDOWN = 'text/markdown';
|
|
|
10
10
|
const UNIVERSAL_SECURENOW_SETUP_PROMPT = `You are working in an existing JavaScript or TypeScript app. Set up SecureNow end-to-end for the framework/runtime already used by this repo. Treat this as a real onboarding, not just a package install.
|
|
11
11
|
|
|
12
12
|
Primary goals:
|
|
13
|
-
- Use the latest published SecureNow npm package. Require securenow@
|
|
13
|
+
- Use the latest published SecureNow npm package. Require securenow@8.0.0 or newer for split admin/runtime credentials and runtime-authenticated ingestion.
|
|
14
14
|
- By default, enable tracing, logs, POST request body capture, multipart metadata capture, and the SecureNow firewall.
|
|
15
15
|
- If I explicitly ask for firewall-only mode, keep the same install/login/verification gates, but use firewall-only preload and do not add tracing, logging, or OTel instrumentation.
|
|
16
16
|
- The firewall must protect the selected SecureNow app, use SecureNow's own blocklist/allowlist/IPDB data, and respect that app's SecureNow AI IPDB confidence threshold. Do not add custom IP reputation providers or custom auto-blocking.
|
|
@@ -18,7 +18,7 @@ Primary goals:
|
|
|
18
18
|
|
|
19
19
|
Safety rules:
|
|
20
20
|
- Do not print full API keys, JWTs, tokens, or local SecureNow credential files (.securenow/admin.json, .securenow/runtime.json, legacy .securenow/credentials.json, or .securenow/credentials.*.json). Mask secrets.
|
|
21
|
-
-
|
|
21
|
+
- Keep local SecureNow credential files secret (.securenow/admin.json, .securenow/runtime.json, legacy .securenow/credentials.json, and .securenow/credentials.*.json). Do not print them; mask secrets in summaries.
|
|
22
22
|
- Do not manually browse to a SecureNow auth URL. Always start auth with npx securenow login so the CLI generates the required callback and state.
|
|
23
23
|
- If the browser says "Missing callback parameter", you opened the wrong URL: rerun npx securenow login from the project root.
|
|
24
24
|
- Do not skip login, app selection, firewall connection, or verification unless I explicitly say to.
|
|
@@ -32,7 +32,7 @@ Runbook:
|
|
|
32
32
|
2. Install or upgrade SecureNow with the detected package manager, using securenow@latest. Verify the actual installed version with:
|
|
33
33
|
node -p "require('./node_modules/securenow/package.json').version"
|
|
34
34
|
npx securenow version
|
|
35
|
-
Stop and fix the install if either is below
|
|
35
|
+
Stop and fix the install if either is below 8.0.0 or npx still resolves an older local package.
|
|
36
36
|
3. Read the installed package surface before editing files: node_modules/securenow/package.json, README/NPM_README, SKILL-API, SKILL-CLI, npx securenow help, and relevant subcommand help for login/init/firewall/doctor/env/test-span/log/mcp.
|
|
37
37
|
4. Mandatory auth/runtime gate:
|
|
38
38
|
- Run npx securenow whoami from the project root.
|
|
@@ -43,10 +43,10 @@ Runbook:
|
|
|
43
43
|
5. Validate project-local credentials without exposing secrets:
|
|
44
44
|
- Confirm .securenow/runtime.json exists for SDK runtime setup, or legacy .securenow/credentials.json exists for old installs.
|
|
45
45
|
- Confirm the runtime file has SecureNow's default config/explanations block.
|
|
46
|
-
- Confirm the runtime file has an app key/name/instance and a
|
|
46
|
+
- Confirm the runtime file has an app key/name/instance and a runtime API key after app selection. The app key only routes telemetry; the runtime API key is required to authenticate telemetry ingestion and firewall sync.
|
|
47
47
|
- Confirm .securenow/admin.json exists only when admin CLI/MCP auth is needed.
|
|
48
48
|
- Confirm .securenow/admin.json, .securenow/runtime.json, legacy .securenow/credentials.json, and any .securenow/credentials.*.json runtime files are ignored by git, without ignoring the entire .securenow/ directory.
|
|
49
|
-
6. Run npx securenow init. If it fails with ui.header is not a function or another CLI bug, upgrade to securenow@latest, verify >=
|
|
49
|
+
6. Run npx securenow init. If it fails with ui.header is not a function or another CLI bug, upgrade to securenow@latest, verify >=8.0.0, and retry. Do not silently ignore init failures.
|
|
50
50
|
7. Configure the least invasive framework-specific integration:
|
|
51
51
|
- Next.js: preserve instrumentation.js/ts. Register securenow/nextjs only when NEXT_RUNTIME is nodejs. In ESM files, use createRequire before require("securenow/nextjs"). Include require("securenow/nextjs-auto-capture") for body capture. For Next 15+, add securenow to serverExternalPackages. For older Next.js, use experimental.serverComponentsExternalPackages. Preserve proxy.js/middleware.js.
|
|
52
52
|
- Nuxt/Nitro: use the documented securenow/nuxt module or Nitro server plugin.
|
|
@@ -61,6 +61,7 @@ Runbook:
|
|
|
61
61
|
- config.firewall.failMode: "open"
|
|
62
62
|
- config.capture.maxBodySize: 10240
|
|
63
63
|
For production, run npx securenow credentials runtime --env production, store the resulting JSON as a deployment secret file, and mount/copy it to <app-root>/.securenow/credentials.json or <app-root>/.securenow/credentials.production.json. Do not recommend env vars unless the user explicitly asks for legacy fallbacks.
|
|
64
|
+
Do not proceed with telemetry verification if the runtime API key is missing; run npx securenow app connect or npx securenow api-key create first. The v8 ingestion gateway rejects app-key-only telemetry.
|
|
64
65
|
Local credentials should use config.runtime.deploymentEnvironment="local". Production runtime credentials should use "production". The app key stays the same; traces, logs, firewall status, forensics, and CLI/MCP queries are scoped by environment.
|
|
65
66
|
9. Verify firewall and threshold:
|
|
66
67
|
- Run npx securenow firewall apps and npx securenow firewall status.
|
package/nextjs.js
CHANGED
|
@@ -31,12 +31,12 @@
|
|
|
31
31
|
*/
|
|
32
32
|
|
|
33
33
|
const { randomUUID } = require('crypto');
|
|
34
|
-
const {
|
|
34
|
+
const { nodeSdkDefaultTelemetryOptions } = require('./otel-defaults');
|
|
35
35
|
const appConfig = require('./app-config');
|
|
36
36
|
const { resolveClientIpWithDetails } = require('./resolve-ip');
|
|
37
37
|
const otelResources = require('@opentelemetry/resources');
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
const nodeSdkTelemetryOptions = nodeSdkDefaultTelemetryOptions();
|
|
40
40
|
|
|
41
41
|
let isRegistered = false;
|
|
42
42
|
|
|
@@ -477,6 +477,7 @@ function registerSecureNow(options = {}) {
|
|
|
477
477
|
});
|
|
478
478
|
|
|
479
479
|
const sdk = new NodeSDK({
|
|
480
|
+
...nodeSdkTelemetryOptions,
|
|
480
481
|
serviceName: serviceName,
|
|
481
482
|
traceExporter: traceExporter,
|
|
482
483
|
instrumentations: [httpInstrumentation],
|
package/nuxt-server-plugin.mjs
CHANGED
|
@@ -20,8 +20,8 @@ import { randomUUID } from 'node:crypto';
|
|
|
20
20
|
const nodeRequire = createRequire(import.meta.url);
|
|
21
21
|
const appConfig = nodeRequire('./app-config');
|
|
22
22
|
const { resolveClientIpWithDetails } = nodeRequire('./resolve-ip');
|
|
23
|
-
const {
|
|
24
|
-
|
|
23
|
+
const { nodeSdkDefaultTelemetryOptions } = nodeRequire('./otel-defaults');
|
|
24
|
+
const nodeSdkTelemetryOptions = nodeSdkDefaultTelemetryOptions();
|
|
25
25
|
|
|
26
26
|
const { NodeSDK } = nodeRequire('@opentelemetry/sdk-node');
|
|
27
27
|
const { OTLPTraceExporter } = nodeRequire('@opentelemetry/exporter-trace-otlp-http');
|
|
@@ -219,6 +219,7 @@ export default defineNitroPlugin(async (nitroApp) => {
|
|
|
219
219
|
const traceExporter = new OTLPTraceExporter({ url: tracesUrl, headers });
|
|
220
220
|
|
|
221
221
|
const sdk = new NodeSDK({
|
|
222
|
+
...nodeSdkTelemetryOptions,
|
|
222
223
|
traceExporter,
|
|
223
224
|
resource,
|
|
224
225
|
instrumentations: [httpInstrumentation],
|
package/otel-defaults.js
CHANGED
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
function isUnset(value) {
|
|
4
|
+
return value == null || String(value).trim() === '';
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function listIncludes(value, needle) {
|
|
8
|
+
return String(value || '')
|
|
9
|
+
.split(',')
|
|
10
|
+
.map((part) => part.trim().toLowerCase())
|
|
11
|
+
.includes(needle);
|
|
12
|
+
}
|
|
13
|
+
|
|
3
14
|
function defaultMetricsExporterToNone(env = process.env) {
|
|
4
15
|
if (!env) return false;
|
|
5
16
|
const current = env.OTEL_METRICS_EXPORTER;
|
|
6
|
-
if (
|
|
17
|
+
if (!isUnset(current)) return false;
|
|
7
18
|
env.OTEL_METRICS_EXPORTER = 'none';
|
|
8
19
|
return true;
|
|
9
20
|
}
|
|
10
21
|
|
|
11
|
-
|
|
22
|
+
function nodeSdkDefaultTelemetryOptions(env = process.env) {
|
|
23
|
+
const options = {};
|
|
24
|
+
|
|
25
|
+
defaultMetricsExporterToNone(env);
|
|
26
|
+
if (listIncludes(env?.OTEL_METRICS_EXPORTER, 'none')) {
|
|
27
|
+
options.metricReaders = [];
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// SecureNow installs its own log exporter. Without this, sdk-node falls back
|
|
31
|
+
// to the upstream OTEL_LOGS_EXPORTER default and tries localhost:4318.
|
|
32
|
+
if (env && isUnset(env.OTEL_LOGS_EXPORTER)) {
|
|
33
|
+
options.logRecordProcessors = [];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return options;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
module.exports = { defaultMetricsExporterToNone, nodeSdkDefaultTelemetryOptions };
|
package/package.json
CHANGED
package/tracing.js
CHANGED
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
* Production should mount/copy tokenless runtime credentials to the same path.
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
|
-
const {
|
|
18
|
-
|
|
17
|
+
const { nodeSdkDefaultTelemetryOptions } = require('./otel-defaults');
|
|
18
|
+
const nodeSdkTelemetryOptions = nodeSdkDefaultTelemetryOptions();
|
|
19
19
|
|
|
20
20
|
const { diag, DiagConsoleLogger, DiagLogLevel, context, trace } = require('@opentelemetry/api');
|
|
21
21
|
const { NodeSDK } = require('@opentelemetry/sdk-node');
|
|
@@ -654,6 +654,7 @@ process.on('unhandledRejection', (reason) => {
|
|
|
654
654
|
// -------- SDK --------
|
|
655
655
|
const traceExporter = new OTLPTraceExporter({ url: tracesUrl, headers });
|
|
656
656
|
const sdk = new NodeSDK({
|
|
657
|
+
...nodeSdkTelemetryOptions,
|
|
657
658
|
traceExporter,
|
|
658
659
|
instrumentations: [
|
|
659
660
|
httpInstrumentation,
|