securenow
v8.0.3
Published
OpenTelemetry instrumentation for Node.js, Next.js, and Nuxt - Send traces and logs to any OTLP-compatible backend
Maintainers
Readme
SecureNow
Zero-config OpenTelemetry for Node.js, Next.js, and Nuxt: traces, logs, body capture, and IP firewall in one install. No env vars. No copy-pasting keys.
Official npm package: securenow
30-second setup
# 1. Install
npm install securenow
# 2. Pick (or create) your app in the browser - writes .securenow/runtime.json.
# The friendly login flow can also refresh admin CLI/MCP auth in .securenow/admin.json.
npx securenow login
# 3. Start your app - one flag is all it takes
node -r securenow/register src/index.jsThat's it. No .env edits, no API keys to paste, no peer-dep warnings. Your traces arrive in the app you picked during login.
package.json example:
"scripts": { "start": "node -r securenow/register src/index.js", "dev": "node -r securenow/register --watch src/index.js" }
How it works
npx securenow login opens a browser and runs both lanes for onboarding:
- admin/control-plane CLI and MCP auth goes to
.securenow/admin.json - app/runtime SDK config and the runtime API key go to
.securenow/runtime.json
During app runtime onboarding, the browser flow returns a one-time plaintext
snk_live_... key scoped to the selected app only. The CLI writes that key as
apiKey in .securenow/runtime.json. Its runtime_app scopes are
traces:write, logs:write, firewall:read, blocklist:read, and
allowlist:read.
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.
Runtime credentials look like:
{
"apiKey": "snk_live_...",
"app": {
"key": "<uuid>",
"name": "my-backend",
"instance": "https://ingest.securenow.ai"
},
"config": {
"runtime": { "deploymentEnvironment": "local" },
"logging": { "enabled": true },
"capture": { "body": true, "multipart": true, "maxBodySize": 10240 },
"firewall": { "enabled": true, "failMode": "open" }
}
}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.
Monorepo / AI-agent setup
If you have many apps under one repo, authenticate once from the repo root:
npx securenow loginThen ask your coding agent to wire each app with this prompt:
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.For production, deploy the tokenless runtime credentials as a secret file mounted at <app-root>/.securenow/credentials.json.
Framework integration
Node.js / Express / Fastify / NestJS / Koa / Hapi
Just add -r securenow/register to your start command. No code changes. Every route, DB call, and console.log is captured automatically.
node -r securenow/register src/app.jsOr with NODE_OPTIONS if you can't change the script:
NODE_OPTIONS="-r securenow/register" npm startNext.js
npx securenow initCreates instrumentation.ts and patches next.config.* when it can do so safely:
// instrumentation.ts
export async function register() {
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
const securenowNext = await import(/* webpackIgnore: true */ 'securenow/nextjs');
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
registerSecureNow({ captureBody: true });
await import(/* webpackIgnore: true */ 'securenow/nextjs-auto-capture');
}For Next.js 15+, init adds securenow to serverExternalPackages and includes the SDK in standalone output when it can safely edit the file:
const nextConfig = {
serverExternalPackages: ['securenow'],
outputFileTracingIncludes: {
'/*': ['./node_modules/securenow/**/*'],
},
};
export default nextConfig;If a custom config or existing instrumentation file needs human judgment, init prints a Codex/Claude-ready prompt with the exact edits to merge.
Nuxt 3
// nuxt.config.ts
export default defineNuxtConfig({
modules: ['securenow/nuxt'],
});Run npx securenow init after installing so the credentials file and secure defaults are created before the app starts.
What's captured automatically
- HTTP spans (Express, Fastify, NestJS, Koa, Hapi, Next.js, Nuxt, raw
http) - Database spans (Postgres, MySQL, MongoDB, Redis)
console.log/info/warn/error/debugforwarded as OTLP logs with trace correlation- Request body capture (JSON, GraphQL, form-encoded) with auto-redaction of
password,token,api_key,authorization,cookie, etc. - Multipart upload metadata (field names, file names, sizes, content-types; never file content)
- Firewall protection from the selected app's SecureNow blocklist and IPDB sync - activates as soon as you've logged in
All of these are on by default. Tune them in .securenow/runtime.json under the config block.
SecureNow does not export metrics by default. The preload sets OTEL_METRICS_EXPORTER=none when the app has not explicitly configured a metrics exporter, which prevents OpenTelemetry's default metrics reader from falling back to localhost:4318.
Production Without Env Vars
Production uses the same file structure. Deploy a tokenless runtime credentials file as a secret file and mount/copy it to:
<app-root>/.securenow/credentials.jsonCreate that runtime file from a logged-in project:
npx securenow credentials runtime --env productionIt 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.
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.
Resolution order:
- Project-local
.securenow/runtime.json - Legacy project-local
.securenow/credentials.json - Project-local named runtime credentials:
.securenow/credentials.staging.json, then.securenow/credentials.production.json, then preview/local/test/development/dev/prod variants - Global
~/.securenow/runtime.json - Legacy global
~/.securenow/credentials.json - Global named runtime credentials in the same fixed order
package.json#name(label only)
SDK runtime config is credentials-json based. Environment-variable fallbacks are no longer supported.
CLI
# Setup
npx securenow login # friendly flow: admin auth + app runtime connection
npx securenow admin login # admin/control-plane CLI + MCP auth only
npx securenow app connect # app/runtime SDK connection only
npx securenow admin login --token <TOKEN> # headless admin auth (CI)
npx securenow init --env local # scaffold framework files + local env scope
npx securenow credentials runtime --env production # write tokenless production credentials file
npx securenow api-key create --name "CLI runtime" # mint + store runtime API key
npx securenow api-key set snk_live_... # store runtime API key in .securenow/runtime.json
# Apps
npx securenow apps # list all apps
npx securenow apps create my-app # create and get the key
npx securenow apps default <key> # change which app this project uses
# Observability
npx securenow traces # list recent traces
npx securenow logs # tail logs
npx securenow status # dashboard summary
npx securenow doctor # diagnose config + connectivity
# Security
npx securenow firewall status --env production
npx securenow blocklist add 1.2.3.4 --reason "scanner"
npx securenow blocklist add 1.2.3.4 --route /admin* --mode prefix --method ALL --reason "admin probing"
npx securenow blocklist unblock <id> --reason "reviewed safe"
npx securenow fp ai-fill --description "Stripe webhook POST /api/stripe/webhook"
# Telemetry from shell (no SDK boot)
npx securenow log send "Deploy succeeded" --level info
npx securenow test-span # verify collector connectivityFull reference: run npx securenow help or see CLI Reference below.
MCP for Codex and Claude
SecureNow ships a local stdio MCP server for agent clients:
npx securenow login
npx securenow admin login # admin/control-plane only
npx securenow app connect # runtime app/API key only
codex mcp add securenow -- npx securenow mcp
# or run directly:
npx -p securenow securenow-mcpThe MCP server resolves credentials by operation type: admin/global tools use .securenow/admin.json, while app-scoped runtime reads can use .securenow/runtime.json or an explicit app key. Legacy combined .securenow/credentials.json remains a fallback. It exposes tools for apps, traces, logs, firewall, IP intelligence, forensics, blocklist/allowlist/trusted IPs, rate-limit remediation, plus resources for the bundled SecureNow docs and setup prompts.
Credentials Config
Use .securenow/runtime.json fields for new local SDK/runtime setups. Production exports still use tokenless .securenow/credentials.<environment>.json files that can be mounted as .securenow/credentials.json.
| Field | Default | Purpose |
|---|---|---|
| app.key | selected during login | App routing UUID; the gateway routes telemetry by this key |
| app.name | selected during login | Human-readable label for CLI and dashboard output |
| 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 |
| config.runtime.deploymentEnvironment | local from init, production from runtime credentials | Sent as OTel deployment.environment |
| config.logging.enabled | true | Forward console.* as OTLP logs |
| config.capture.body | true | Capture JSON / form request bodies with redaction |
| config.capture.multipart | true | Capture multipart metadata, never file content |
| config.capture.maxBodySize | 10240 | Max bytes captured per body |
| config.capture.sensitiveFields | [] | Extra field-name fragments to redact |
| config.firewall.enabled | Deprecated | Ignored as a local kill switch; dashboard/API firewall toggle is scoped per environment |
| config.otel.* | empty | Optional custom OTLP endpoints, headers, and log level |
The credentials file is versioned with _securenow.schemaVersion, so future SDK
versions can migrate defaults without asking customers to manage env vars. For
production, generate a tokenless runtime file:
npx securenow credentials runtime --env productionMount or copy that JSON as .securenow/credentials.json in the deployed app.
New runtime credentials do not include a per-instance collector URL; the SDK
uses https://ingest.securenow.ai by default and the gateway routes by
app.key.
Environment-variable fallback is not supported; use runtime credentials files
for local, staging, preview, and production.
Supported frameworks
Web
Next.js (App & Pages Router), Nuxt 3, Express, Fastify, NestJS, Koa, Hapi
Databases
PostgreSQL, MySQL / MySQL2, MongoDB, Redis
Other
HTTP/HTTPS, GraphQL, gRPC, and many more via @opentelemetry/auto-instrumentations-node.
MongoDB instrumentation is included in the current SDK. To disable it for a service, add
@opentelemetry/instrumentation-mongodbtoconfig.otel.disableInstrumentationsin.securenow/runtime.json.
Documentation
The npm package ships the current setup references: this README, NPM_README.md, SKILL-API.md, SKILL-CLI.md, and the MCP resources exposed by npx securenow mcp. Older long-form guides are kept in the repository only so customer installs do not receive stale .env-first instructions.
CLI Reference
After install, the securenow CLI is available via npx securenow or globally with npm install -g securenow.
Run (convenience wrapper)
| Command | Description |
|---|---|
| securenow run <script> | Run a Node app with -r securenow/register injected |
| securenow run --watch <script> | Same, with Node.js watch mode |
| securenow run --firewall-only <script> | Preload the firewall only, skip OTel |
Authentication
| Command | Description |
|---|---|
| securenow login | Friendly onboarding: admin auth + runtime app connection |
| securenow admin login | Admin/control-plane CLI and MCP auth only |
| securenow app connect | App/runtime SDK connection only |
| securenow login --global | Save to ~/.securenow/ instead |
| securenow admin login --token <TOKEN> | Headless admin auth (CI/servers) |
| securenow logout | Clear admin auth only; runtime app config stays intact |
| securenow logout --global | Clear ~/.securenow/ instead |
| securenow whoami | Show admin auth and runtime app status separately |
| 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 |
| securenow api-key set <snk_live_...> | Store runtime API key in .securenow/runtime.json (--global for ~/.securenow/) |
| securenow api-key show | Print masked key + source file |
| securenow api-key clear | Remove stored key (--global for ~/.securenow/) |
Applications
| Command | Description |
|---|---|
| securenow apps | List all apps for your account |
| securenow apps create <name> | Create an app |
| securenow apps info <id> | Show app details |
| securenow apps delete <id> | Delete an app |
| securenow apps default <key> | Switch which app this project uses (updates .securenow/) |
Observability
| Command | Description |
|---|---|
| securenow traces | Recent traces |
| securenow traces show <traceId> | Trace spans |
| securenow traces analyze <traceId> | AI security analysis |
| securenow logs | View logs (--minutes, --level) |
| securenow logs trace <traceId> | Logs for a trace |
| securenow analytics | Response code analytics |
| securenow status | Dashboard summary |
Detect & Respond
| Command | Description |
|---|---|
| securenow notifications | List notifications |
| securenow notifications unread | Unread count |
| securenow alerts rules | List alert rules |
| securenow alerts rules dry-run-query <id> --sql @candidate.sql --wait | Dry-run candidate alert SQL without saving |
| securenow alerts rules tune-query <id> --sql @candidate.sql --apply-globally --yes | Admin: update a shared system rule query mapping |
| securenow alerts history | Alert history |
Investigate
| Command | Description |
|---|---|
| securenow ip <address> | IP intel (geo, abuse, verdict) |
| securenow ip traces <address> | Traces from an IP |
| securenow forensics "<query>" | Natural language forensic query |
| securenow api-map | Discovered API endpoints |
Firewall
| Command | Description |
|---|---|
| securenow firewall status | Firewall layers + key info |
| securenow firewall test-ip <ip> [--path /admin/users] | Would this IP be blocked? |
Remediation
| Command | Description |
|---|---|
| securenow blocklist | List blocked IPs |
| securenow blocklist add <ip> [--route /admin*] [--mode prefix] [--method GET] [--reason ...] | Block an IP globally or only for matching routes |
| securenow blocklist unblock <id> [--reason ...] | Stop enforcement and keep block history |
| securenow ratelimit parse "<request>" | Fill a rate-limit rule draft from natural language |
| securenow ratelimit from-text "<request>" --yes | Create a soft rate-limit rule from natural language |
| securenow allowlist add <ip> | Allow an IP (restrict-mode) |
| securenow trusted add <ip> | Mark an IP as trusted |
False positives
| Command | Description |
|---|---|
| securenow fp | List exclusion rules |
| securenow fp ai-fill --description "..." | AI-generate exclusion conditions |
| securenow fp mark <notif-id> <ip> | Mark an alert as a false positive |
| securenow fp dry-run --conditions '[...]' | Test against last 3 days of traces |
Telemetry from the shell
| Command | Description |
|---|---|
| securenow log send "<msg>" [--level info\|warn\|error] | Emit a log record via OTLP |
| securenow test-span | Send a test span |
Diagnostics & utilities
| Command | Description |
|---|---|
| securenow doctor | Probe OTLP + API, check config |
| securenow env | Show resolved config |
| securenow redact '<json>' | Preview redaction |
| securenow cidr match <ip> <cidr> | Test CIDR match (exit 0/2) |
Global flags
| Flag | Effect |
|---|---|
| --json | Machine-readable output |
| --help | Help for any command |
| --app <key> | Override which app |
| --global | Global credentials scope (login/logout) |
Where things live
| File | Purpose |
|---|---|
| ./.securenow/admin.json | Project-local admin/control-plane CLI and MCP auth |
| ./.securenow/runtime.json | Project-local SDK runtime app config and runtime API key |
| ./.securenow/credentials.json | Legacy combined credentials; still read for backward compatibility |
| ./.securenow/credentials.<environment>.json | Tokenless runtime file generated by securenow credentials runtime --env <environment>; read in a fixed order, not selected from env vars |
| ~/.securenow/admin.json | Global admin/control-plane auth |
| ~/.securenow/runtime.json | Global SDK runtime app config |
| ~/.securenow/credentials.json | Legacy global combined credentials |
| ~/.securenow/credentials.<environment>.json | Global environment-specific runtime credentials |
| ~/.securenow/config.json | API URL, default app, preferences |
Runtime resolution order: project .securenow/runtime.json -> legacy project .securenow/credentials.json -> project named runtime credentials in fixed staging/production/preview/local/test/development/dev/prod order -> global ~/.securenow/runtime.json -> legacy global credentials -> global named runtime credentials -> package name fallback. Admin auth resolves from admin.json first, then legacy credentials.json. Runtime config is never read from environment variables.
Override the dashboard API with securenow config set apiUrl <url>.
Support
- Website: securenow.ai
- Docs: this README,
NPM_README.md,SKILL-API.md,SKILL-CLI.md, andnpx securenow help - Issues: report bugs and requests on GitHub
License
ISC
