securenow 8.0.2 → 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/README.md +3 -3
- package/SKILL-API.md +4 -4
- package/SKILL-CLI.md +1 -1
- package/app-config.js +1 -1
- package/cli/credentials.js +1 -1
- package/mcp/catalog.js +1 -1
- 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/README.md
CHANGED
|
@@ -66,7 +66,7 @@ Runtime credentials look like:
|
|
|
66
66
|
}
|
|
67
67
|
```
|
|
68
68
|
|
|
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.
|
|
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.
|
|
70
70
|
|
|
71
71
|
---
|
|
72
72
|
|
|
@@ -81,7 +81,7 @@ npx securenow login
|
|
|
81
81
|
Then ask your coding agent to wire each app with this prompt:
|
|
82
82
|
|
|
83
83
|
```text
|
|
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
|
|
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.
|
|
85
85
|
```
|
|
86
86
|
|
|
87
87
|
For production, deploy the tokenless runtime credentials as a secret file mounted at `<app-root>/.securenow/credentials.json`.
|
|
@@ -169,7 +169,7 @@ SecureNow does not export metrics by default. The preload sets `OTEL_METRICS_EXP
|
|
|
169
169
|
|
|
170
170
|
## Production Without Env Vars
|
|
171
171
|
|
|
172
|
-
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:
|
|
173
173
|
|
|
174
174
|
```text
|
|
175
175
|
<app-root>/.securenow/credentials.json
|
package/SKILL-API.md
CHANGED
|
@@ -70,7 +70,7 @@ 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
74
|
|
|
75
75
|
The automatically created key is scoped to the selected app only. Its
|
|
76
76
|
`runtime_app` scopes are `traces:write`, `logs:write`, `firewall:read`,
|
|
@@ -224,7 +224,7 @@ On Vercel it uses `@vercel/otel`; self-hosted uses vanilla `@opentelemetry/sdk-n
|
|
|
224
224
|
}
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
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`.
|
|
228
228
|
|
|
229
229
|
#### Next.js Body Capture
|
|
230
230
|
|
|
@@ -595,7 +595,7 @@ npm install securenow@latest
|
|
|
595
595
|
npx securenow login
|
|
596
596
|
```
|
|
597
597
|
|
|
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
|
|
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.
|
|
599
599
|
|
|
600
600
|
Update `package.json`:
|
|
601
601
|
```json
|
|
@@ -611,7 +611,7 @@ npm install securenow@latest
|
|
|
611
611
|
npx securenow app connect # pick/create app; runtime API key is minted automatically
|
|
612
612
|
```
|
|
613
613
|
|
|
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
|
|
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.
|
|
615
615
|
|
|
616
616
|
### Enable Firewall With Zero Tracing Overhead
|
|
617
617
|
|
package/SKILL-CLI.md
CHANGED
|
@@ -180,7 +180,7 @@ securenow init [--env local] [--key <API_KEY>]
|
|
|
180
180
|
```
|
|
181
181
|
|
|
182
182
|
Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
|
|
183
|
-
- **Credentials**: ensures `.securenow/runtime.json` exists
|
|
183
|
+
- **Credentials**: ensures `.securenow/runtime.json` exists with secure defaults and explanations
|
|
184
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
|
|
185
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
|
|
186
186
|
- **Nuxt**: tells you to add `securenow/nuxt` to modules
|
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/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/mcp/catalog.js
CHANGED
|
@@ -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.
|
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,
|