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 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. Local credential files are auto-added to `.gitignore` so they never land in git.
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, gitignore only SecureNow credential files, 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.
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. Do not commit `.securenow/`; instead deploy a tokenless runtime credentials file as a secret file and mount/copy it to:
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` (gitignored via credential-file patterns, not a whole-directory `.securenow/` ignore) 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`.
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 gitignored. For production, run `npx securenow credentials runtime --env production` and mount/copy the generated JSON as `.securenow/credentials.json` or `.securenow/credentials.production.json`.
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 is gitignored without ignoring the whole `.securenow/` directory.
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` (gitignored via credential-file patterns, not a whole-directory `.securenow/` ignore). 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.
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, has secure defaults/explanations, and local credential JSON files are gitignored without ignoring the whole `.securenow/` directory
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; keep .securenow/ in .gitignore.',
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
  });
@@ -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. Do not commit it.',
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
- - Do not commit secrets. Ignore only local SecureNow credential files (.securenow/admin.json, .securenow/runtime.json, .securenow/credentials.json, and .securenow/credentials.*.json); keep the .securenow/ directory itself trackable for repo-owned docs/templates.
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 { defaultMetricsExporterToNone } = require('./otel-defaults');
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
- defaultMetricsExporterToNone();
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],
@@ -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 { defaultMetricsExporterToNone } = nodeRequire('./otel-defaults');
24
- defaultMetricsExporterToNone();
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 (current != null && String(current).trim() !== '') return false;
17
+ if (!isUnset(current)) return false;
7
18
  env.OTEL_METRICS_EXPORTER = 'none';
8
19
  return true;
9
20
  }
10
21
 
11
- module.exports = { defaultMetricsExporterToNone };
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "8.0.2",
3
+ "version": "8.0.3",
4
4
  "description": "OpenTelemetry instrumentation for Node.js, Next.js, and Nuxt - Send traces and logs to any OTLP-compatible backend",
5
5
  "type": "commonjs",
6
6
  "main": "register.js",
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 { defaultMetricsExporterToNone } = require('./otel-defaults');
18
- defaultMetricsExporterToNone();
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,