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
npm install securenow
npx securenow login
node -r securenow/register src/index.js
That'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 login
Then 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.js
Or with NODE_OPTIONS if you can't change the script:
NODE_OPTIONS="-r securenow/register" npm start
Next.js
npx securenow init
Creates instrumentation.ts and patches next.config.* when it can do so safely:
export async function register() {
if (process.env.NEXT_RUNTIME !== 'nodejs') return;
const securenowNext = await import( 'securenow/nextjs');
const registerSecureNow = securenowNext.registerSecureNow || securenowNext.default?.registerSecureNow;
registerSecureNow({ captureBody: true });
await import( '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
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/debug forwarded 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.json
Create that runtime file from a logged-in project:
npx securenow credentials runtime --env production
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.
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
npx securenow login
npx securenow admin login
npx securenow app connect
npx securenow admin login --token <TOKEN>
npx securenow init --env local
npx securenow credentials runtime --env production
npx securenow api-key create --name "CLI runtime"
npx securenow api-key set snk_live_...
npx securenow apps
npx securenow apps create my-app
npx securenow apps default <key>
npx securenow traces
npx securenow logs
npx securenow status
npx securenow doctor
npx securenow telemetry schema --json
npx securenow telemetry fields --app <key> --env production --since 24h --json
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"
npx securenow log send "Deploy succeeded" --level info
npx securenow test-span
Full 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
npx securenow app connect
codex mcp add securenow -- npx securenow mcp
npx -p securenow securenow-mcp
The 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.
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 production
Mount 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-mongodb to config.otel.disableInstrumentations in .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)
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
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
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
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 |
Detection authoring
securenow telemetry schema --json | Offline, versioned tables, fields, event mappings, tenant scope, and SQL requirements |
securenow telemetry fields --app <key> --env production --since 24h --json | Fields, types, and custom event names actually observed for an authorized app; values are never returned |
securenow alerts rules validate --sql @rule.sql --app <key> | Compile and dry-run candidate SQL before creating a rule |
The machine-readable contract is also exported as require('securenow/telemetry-schema'); the full workflow and SQL examples are in TELEMETRY-SQL.md.
Detect & Respond
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
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
securenow firewall status | Firewall layers + key info |
securenow firewall test-ip <ip> [--path /admin/users] | Would this IP be blocked? |
Remediation
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
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
securenow log send "<msg>" [--level info|warn|error] | Emit a log record via OTLP |
securenow test-span | Send a test span |
Diagnostics & utilities
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
--json | Machine-readable output |
--help | Help for any command |
--app <key> | Override which app |
--global | Global credentials scope (login/logout) |
Where things live
./.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, and npx securenow help
- Issues: report bugs and requests on GitHub
License
ISC