securenow 5.14.0 → 5.15.0

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/SKILL-CLI.md ADDED
@@ -0,0 +1,395 @@
1
+ # SecureNow CLI — Agent Skill
2
+
3
+ Use the `securenow` CLI to perform security DevOps from the terminal: manage apps, investigate threats, control the firewall, analyze traces, handle false positives, and run instrumented Node.js processes. Every command supports `--json` for machine-readable output.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ # Install globally (recommended for CLI usage)
9
+ npm install -g securenow
10
+
11
+ # Or install per-project and use via npx
12
+ npm install securenow
13
+ npx securenow <command>
14
+ ```
15
+
16
+ ### Authenticate
17
+
18
+ ```bash
19
+ securenow login # opens browser OAuth; stores JWT in ~/.securenow/credentials.json
20
+ securenow login --token <JWT> # headless / CI login (get token from dashboard Settings)
21
+ securenow whoami # verify session
22
+ ```
23
+
24
+ ### Integrate With Your App
25
+
26
+ The CLI can also instrument any Node.js app at launch — no code changes:
27
+
28
+ ```bash
29
+ # Express, Fastify, NestJS, Koa, Hapi, raw Node.js
30
+ securenow run src/index.js
31
+
32
+ # Or via the Node preload flag
33
+ node -r securenow/register src/index.js
34
+ ```
35
+
36
+ For Next.js, run the interactive scaffolding:
37
+
38
+ ```bash
39
+ securenow init --key snk_live_...
40
+ ```
41
+
42
+ This auto-detects your framework and creates the necessary `instrumentation.ts`, `next.config.js` changes, and writes your API key to `.env.local`.
43
+
44
+ ### Install This Skill in Cursor
45
+
46
+ Save this file as `.cursor/skills/securenow-cli/SKILL.md` in your project. Your AI agent will auto-discover it whenever you ask about CLI commands, security investigations, or firewall management.
47
+
48
+ ## Configuration
49
+
50
+ Config lives in `~/.securenow/`:
51
+
52
+ | File | Content |
53
+ |------|---------|
54
+ | `config.json` | `apiUrl`, `appUrl`, `defaultApp`, `output` |
55
+ | `credentials.json` | `token`, `email`, `expiresAt` |
56
+
57
+ ```bash
58
+ securenow config set apiUrl https://api.securenow.ai
59
+ securenow config set defaultApp my-app-key
60
+ securenow config get # show all
61
+ securenow config get defaultApp # show one
62
+ securenow config path # print file paths
63
+ ```
64
+
65
+ Environment overrides: `SECURENOW_API_URL`, `SECURENOW_APP_URL`, `SECURENOW_APP` (default app key).
66
+
67
+ ## Global Flags
68
+
69
+ | Flag | Short | Effect |
70
+ |------|-------|--------|
71
+ | `--json` | `-j` | JSON output (pipe-friendly) |
72
+ | `--help` | | Show help for any command |
73
+ | `--verbose` | `-v` | Verbose output |
74
+ | `--force` | `-f` | Skip confirmations |
75
+ | `--yes` | `-y` | Auto-confirm prompts |
76
+
77
+ Debug mode: `SECURENOW_DEBUG=1 securenow <cmd>` prints stack traces on errors.
78
+
79
+ ---
80
+
81
+ ## Command Reference
82
+
83
+ ### Run — Instrument Any Node.js App
84
+
85
+ ```bash
86
+ securenow run <script> # auto-detect CJS/ESM, inject OTel preload
87
+ securenow run --watch src/index.js # pass Node flags through
88
+ securenow run --inspect src/server.js --port 3000
89
+ securenow src/index.js # shorthand — auto-detected as "run"
90
+ ```
91
+
92
+ Spawns `node --require securenow/register [--import otel/hook.mjs] <script>`. ESM detection uses nearest `package.json` `"type"` field or `.mjs`/`.cjs` extension.
93
+
94
+ ### Authentication
95
+
96
+ ```bash
97
+ securenow login # browser-based OAuth (starts local callback server)
98
+ securenow login --token <JWT> # headless / CI login
99
+ securenow logout # clear ~/.securenow/credentials.json
100
+ securenow whoami # show email, user ID, API URL, expiry, default app
101
+ ```
102
+
103
+ ### Applications
104
+
105
+ ```bash
106
+ securenow apps # list all apps (default subcommand)
107
+ securenow apps list # same as above
108
+ securenow apps create <name> [--hosts h1,h2] [--instance <id>] # interactive instance picker
109
+ securenow apps info <id> # show app details
110
+ securenow apps delete <id> [--force] # delete an app
111
+ securenow apps default <app-key> # set default app for all commands
112
+ securenow apps discover [appId] [--domain example.com] # discover subdomains, add as apps
113
+ securenow apps scan [--yes] # scan all app domains for new subdomains
114
+ ```
115
+
116
+ ### Init — Project Setup
117
+
118
+ ```bash
119
+ securenow init [--key <API_KEY>]
120
+ ```
121
+
122
+ Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
123
+ - **Next.js**: creates `instrumentation.ts/js`, suggests `withSecureNow()` in `next.config`
124
+ - **Nuxt**: tells you to add `securenow/nuxt` to modules
125
+ - **Node/Express/etc.**: suggests adding `-r securenow/register` to start script
126
+ - Writes `SECURENOW_API_KEY` to `.env.local` or `.env` if `--key` provided
127
+
128
+ ### Dashboard & Status
129
+
130
+ ```bash
131
+ securenow status [--app <key>] # dashboard overview
132
+ securenow analytics [--app <key>] # response analytics
133
+ ```
134
+
135
+ ---
136
+
137
+ ### Traces
138
+
139
+ ```bash
140
+ securenow traces [--app <key>] [--limit N] [--start ISO] [--end ISO]
141
+ securenow traces list --app my-app --limit 50
142
+ securenow traces show <traceId> # full trace detail with spans
143
+ securenow traces analyze <traceId> # AI-powered trace analysis
144
+ ```
145
+
146
+ ### Logs
147
+
148
+ ```bash
149
+ securenow logs [--app <key>] [--limit N] [--minutes M] [--level error|warn|info]
150
+ securenow logs list --app my-app --minutes 30 --level error
151
+ securenow logs trace <traceId> # logs correlated to a specific trace
152
+ ```
153
+
154
+ ### Issues
155
+
156
+ ```bash
157
+ securenow issues [--app <key>] [--status open|resolved]
158
+ securenow issues list --status open
159
+ securenow issues show <id> # full issue details
160
+ securenow issues resolve <id> # mark as resolved
161
+ ```
162
+
163
+ ### Notifications
164
+
165
+ ```bash
166
+ securenow notifications [--limit N] [--page P]
167
+ securenow notifications list --limit 20
168
+ securenow notifications read <id> # mark one as read
169
+ securenow notifications read-all # mark all as read
170
+ securenow notifications unread # unread count
171
+ ```
172
+
173
+ ### Alerts
174
+
175
+ ```bash
176
+ securenow alerts # list alert rules (default)
177
+ securenow alerts rules # list alert rules
178
+ securenow alerts channels # list alert channels (Slack, email, etc.)
179
+ securenow alerts history [--limit N] # past triggered alerts
180
+ ```
181
+
182
+ ---
183
+
184
+ ### IP Intelligence
185
+
186
+ ```bash
187
+ securenow ip <ip-address> # lookup (geo, ASN, threat score, reputation)
188
+ securenow ip lookup <ip-address> # same as above
189
+ securenow ip traces <ip-address> # traces originating from this IP
190
+ ```
191
+
192
+ ### Forensics — Natural Language Security Queries
193
+
194
+ ```bash
195
+ securenow forensics "show me all SQL injection attempts in the last 24h"
196
+ securenow forensics query "top 10 IPs by blocked requests" --app my-app
197
+ securenow forensics chat --app my-app # interactive forensics chat session
198
+ securenow forensics library # view saved/template queries
199
+ ```
200
+
201
+ ### API Map
202
+
203
+ ```bash
204
+ securenow api-map # list discovered API endpoints
205
+ securenow api-map list # same
206
+ securenow api-map stats # endpoint statistics
207
+ ```
208
+
209
+ ---
210
+
211
+ ### Firewall
212
+
213
+ ```bash
214
+ securenow firewall # show status (default)
215
+ securenow firewall status # layers, sync time, blocked count, API key info
216
+ securenow firewall test-ip <ip> # check if IP would be blocked
217
+ ```
218
+
219
+ ### Blocklist — Block Malicious IPs
220
+
221
+ ```bash
222
+ securenow blocklist # list blocked IPs
223
+ securenow blocklist list
224
+ securenow blocklist add <ip> [--reason "Brute force"]
225
+ securenow blocklist remove <id>
226
+ securenow blocklist stats # block counts, top reasons
227
+ ```
228
+
229
+ ### Allowlist — Restrict to Known IPs
230
+
231
+ ```bash
232
+ securenow allowlist # list allowed IPs
233
+ securenow allowlist list
234
+ securenow allowlist add <ip> [--label "Office"] [--reason "Corporate VPN"]
235
+ securenow allowlist remove <id>
236
+ securenow allowlist stats
237
+ ```
238
+
239
+ ### Trusted Proxies
240
+
241
+ ```bash
242
+ securenow trusted # list trusted IPs
243
+ securenow trusted list
244
+ securenow trusted add <ip> [--label "CloudFlare edge"]
245
+ securenow trusted remove <id>
246
+ ```
247
+
248
+ ---
249
+
250
+ ### False Positive Management
251
+
252
+ The `fp` command manages exclusion rules that prevent known-safe traffic from triggering security alerts.
253
+
254
+ ```bash
255
+ securenow fp # list all exclusion rules
256
+ securenow fp list
257
+ securenow fp show <id> # rule details
258
+ securenow fp delete <id> [--yes]
259
+
260
+ # Create exclusion rules
261
+ securenow fp create \
262
+ --conditions '[{"field":"http.target","op":"starts_with","value":"/api/health"}]' \
263
+ --match-mode all \
264
+ --rule-scope any_rule \
265
+ --reason "Health check endpoint"
266
+
267
+ # Shorthand safe-value presets
268
+ securenow fp create \
269
+ --path /api/events \
270
+ --method POST \
271
+ --path-safe standard \
272
+ --ua-safe standard \
273
+ --headers-safe standard \
274
+ --query-keys page,limit \
275
+ --headers-keys host,content-type \
276
+ --reason "Event webhook"
277
+
278
+ # Edit an existing rule
279
+ securenow fp edit <id> [--active true|false] [--conditions '[...]']
280
+
281
+ # Test conditions against a request body
282
+ securenow fp test-body '{"user":"admin"}' --conditions '[{"field":"body.user","op":"eq","value":"admin"}]'
283
+ securenow fp test-body @request.json --conditions '[...]'
284
+
285
+ # Dry-run conditions against the last 3 days of live traces
286
+ securenow fp dry-run --conditions '[{"field":"http.target","op":"starts_with","value":"/api/webhook"}]'
287
+
288
+ # AI-generate exclusion conditions from a description
289
+ securenow fp ai-fill --description "Stripe webhook POST to /api/stripe/webhook" \
290
+ --context '{"method":"POST","path":"/api/stripe/webhook"}'
291
+
292
+ # Mark an IP as false positive on a specific notification
293
+ securenow fp mark <notification-id> <ip> \
294
+ [--conditions '[...]'] \
295
+ [--reason "Known partner IP"] \
296
+ [--rule-scope this_rule|specific_rules|all_existing|any_rule] \
297
+ [--target-rules id1,id2]
298
+ ```
299
+
300
+ **Condition fields:** `http.target`, `http.method`, `http.url`, `http.user_agent`, `http.request.header.*`, `body.*`, `http.status_code`, `net.peer.ip`, and more.
301
+
302
+ **Operators:** `eq`, `neq`, `contains`, `not_contains`, `starts_with`, `ends_with`, `regex`, `in`, `not_in`, `exists`, `not_exists`, `gt`, `lt`, `gte`, `lte`.
303
+
304
+ **Match modes:** `all` (AND logic), `any` (OR logic).
305
+
306
+ **Rule scopes:** `this_rule` (single alert rule), `specific_rules` (comma-separated IDs via `--target-rules`), `all_existing` (all current rules), `any_rule` (all current and future rules).
307
+
308
+ **Safe-value presets:** `standard` or `strict`. These auto-generate conditions that whitelist common safe patterns for paths, query strings, user-agents, and headers.
309
+
310
+ ---
311
+
312
+ ### Instances
313
+
314
+ ```bash
315
+ securenow instances # list ClickHouse instances
316
+ securenow instances list
317
+ securenow instances test <id> # test connection
318
+ ```
319
+
320
+ ---
321
+
322
+ ## Workflow Examples for Agentic AI
323
+
324
+ ### Investigate a Security Alert
325
+
326
+ ```bash
327
+ securenow notifications list --limit 5 --json
328
+ securenow issues show <issue-id> --json
329
+ securenow ip <attacker-ip> --json
330
+ securenow ip traces <attacker-ip> --json
331
+ securenow traces show <trace-id> --json
332
+ securenow traces analyze <trace-id> --json
333
+ # Decision: block the IP
334
+ securenow blocklist add <attacker-ip> --reason "Automated: SQL injection from issue #<id>"
335
+ ```
336
+
337
+ ### Triage and Suppress a False Positive
338
+
339
+ ```bash
340
+ securenow notifications list --json
341
+ # Identify a false positive notification
342
+ securenow fp ai-fill --description "Stripe webhook calls to /api/stripe/webhook"
343
+ # Review the suggested conditions, then create the rule
344
+ securenow fp create --conditions '<ai-suggested-conditions>' --rule-scope any_rule --reason "Stripe webhook"
345
+ # Or directly mark the notification's IP as FP
346
+ securenow fp mark <notification-id> <ip> --rule-scope this_rule --reason "Known Stripe IP"
347
+ ```
348
+
349
+ ### Onboard a New Application
350
+
351
+ ```bash
352
+ securenow apps create my-new-app --hosts api.example.com,app.example.com
353
+ securenow apps default my-new-app
354
+ securenow init --key snk_live_abc123...
355
+ securenow run src/index.js
356
+ securenow status --json
357
+ ```
358
+
359
+ ### Security Posture Check
360
+
361
+ ```bash
362
+ securenow status --json
363
+ securenow firewall status --json
364
+ securenow blocklist stats --json
365
+ securenow api-map stats --json
366
+ securenow issues list --status open --json
367
+ securenow forensics "summarize all attacks in the last 7 days"
368
+ ```
369
+
370
+ ### Discover Attack Surface
371
+
372
+ ```bash
373
+ securenow apps discover --domain example.com
374
+ securenow apps scan --yes
375
+ securenow api-map list --json
376
+ securenow api-map stats --json
377
+ ```
378
+
379
+ ---
380
+
381
+ ## Output Parsing
382
+
383
+ All commands support `--json` for structured output. When piping to other tools or parsing programmatically, always use `--json`. Table output is the default for human readability.
384
+
385
+ ## Error Handling
386
+
387
+ | Exit code / Error | Meaning | Recovery |
388
+ |------------------|---------|----------|
389
+ | `Session expired` | JWT expired | `securenow login` |
390
+ | `Not logged in` | No token in `~/.securenow/credentials.json` | `securenow login` |
391
+ | `Access denied (403)` | Insufficient plan or permissions | Upgrade plan or check user role |
392
+ | `Cannot connect` | API unreachable | Check `SECURENOW_API_URL` or network |
393
+ | `Unknown command` | Typo or unrecognized command | `securenow help` |
394
+
395
+ Set `SECURENOW_DEBUG=1` for full stack traces on any error.
package/cli.js CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env node
1
+ #!/usr/bin/env node
2
2
  'use strict';
3
3
 
4
4
  const ui = require('./cli/ui');
@@ -29,7 +29,14 @@ Internet Traffic
29
29
  Your App
30
30
  ```
31
31
 
32
- All layers share the same in-memory blocklist, synced every 60 seconds from the SecureNow API. Layer 1 (HTTP) is always active. Layers 24 are opt-in via environment variables.
32
+ All layers share the same in-memory blocklist, synced from the SecureNow API using a version-based protocol. Layer 1 (HTTP) is always active. Layers 2-4 are opt-in via environment variables.
33
+
34
+ **Sync protocol:**
35
+ - A lightweight version check runs every 10 seconds (uses ETag/304 -- no data transferred when unchanged)
36
+ - Full blocklist sync only when the version changes, or every 5 minutes as a safety net
37
+ - Changes propagate to all running instances in 10-15 seconds
38
+ - Exponential backoff with jitter when the API is temporarily unreachable
39
+ - Automatic localhost fallback when API is co-located (ECONNREFUSED triggers retry on `http://localhost:4000`)
33
40
 
34
41
  ---
35
42
 
@@ -69,9 +76,18 @@ That's it. The firewall auto-activates when `SECURENOW_API_KEY` is present. You'
69
76
  [securenow] Firewall: Layer 3 (iptables) disabled (set SECURENOW_FIREWALL_IPTABLES=1)
70
77
  [securenow] Firewall: Layer 4 (Cloud WAF) disabled (set SECURENOW_FIREWALL_CLOUD=cloudflare|aws|gcp)
71
78
  [securenow] Firewall: synced 142 blocked IPs (138 exact + 4 CIDR ranges)
72
- [securenow] Firewall: next sync in 60s
73
79
  ```
74
80
 
81
+ ### Firewall-Only Mode (No Tracing)
82
+
83
+ If you only need IP blocking without OpenTelemetry tracing:
84
+
85
+ ```bash
86
+ node -r securenow/firewall-only app.js
87
+ ```
88
+
89
+ This loads only the firewall with zero OTel dependencies. No `serverExternalPackages`, no `instrumentation.js`, no tracing overhead. Set `SECURENOW_API_KEY` in your environment and you're done.
90
+
75
91
  ---
76
92
 
77
93
  ## Layers In Detail
@@ -176,12 +192,13 @@ SECURENOW_FIREWALL_CLOUD_DRY_RUN=1
176
192
  | Variable | Default | Description |
177
193
  |----------|---------|-------------|
178
194
  | `SECURENOW_API_KEY` | *(required)* | API key with `firewall:read` scope |
179
- | `SECURENOW_API_URL` | `https://api.securenow.ai` | API base URL |
195
+ | `SECURENOW_API_URL` | `https://api.securenow.ai` | API base URL. Auto-fallback to `http://localhost:4000` on ECONNREFUSED. |
180
196
  | `SECURENOW_FIREWALL_ENABLED` | `1` | Master kill-switch (`0` to disable) |
181
- | `SECURENOW_FIREWALL_SYNC_INTERVAL` | `60` | Seconds between blocklist refreshes |
197
+ | `SECURENOW_FIREWALL_VERSION_INTERVAL` | `10` | Seconds between version checks (lightweight ETag-based) |
198
+ | `SECURENOW_FIREWALL_SYNC_INTERVAL` | `300` | Full blocklist refresh interval in seconds (safety net) |
182
199
  | `SECURENOW_FIREWALL_FAIL_MODE` | `open` | `open` = allow when list unavailable; `closed` = block all |
183
200
  | `SECURENOW_FIREWALL_STATUS_CODE` | `403` | HTTP status code for blocked requests (Layer 1) |
184
- | `SECURENOW_FIREWALL_LOG` | `1` | Log blocked requests to console |
201
+ | `SECURENOW_FIREWALL_LOG` | `1` | Log blocked requests to console (`0` to silence) |
185
202
  | `SECURENOW_FIREWALL_TCP` | `0` | Enable Layer 2 TCP blocking |
186
203
  | `SECURENOW_FIREWALL_IPTABLES` | `0` | Enable Layer 3 iptables/nftables blocking |
187
204
  | `SECURENOW_FIREWALL_CLOUD` | *(none)* | Cloud WAF provider: `cloudflare`, `aws`, or `gcp` |
@@ -216,16 +233,24 @@ SECURENOW_INSTANCE=https://freetrial.securenow.ai:4318
216
233
  SECURENOW_API_KEY=snk_live_abc123...
217
234
  ```
218
235
 
219
- Works automatically with `instrumentation.ts`:
236
+ ```javascript
237
+ // next.config.js
238
+ const { withSecureNow } = require('securenow/nextjs-webpack-config');
239
+ module.exports = withSecureNow({ /* your config */ });
240
+ ```
220
241
 
221
242
  ```typescript
243
+ // instrumentation.ts
222
244
  export async function register() {
223
245
  if (process.env.NEXT_RUNTIME === 'nodejs') {
224
- await import('securenow/register');
246
+ const { registerSecureNow } = require('securenow/nextjs');
247
+ registerSecureNow();
225
248
  }
226
249
  }
227
250
  ```
228
251
 
252
+ The firewall initializes independently from OpenTelemetry -- it works even if tracing setup encounters an error.
253
+
229
254
  ### PM2 Cluster
230
255
 
231
256
  ```javascript
@@ -294,7 +319,7 @@ npx securenow blocklist remove <id>
294
319
  npx securenow blocklist stats
295
320
  ```
296
321
 
297
- Changes take effect on the next sync interval (default 60 seconds).
322
+ Changes take effect on the next version check (default every 10 seconds). Trusted IP changes also trigger immediate cache invalidation on the API side.
298
323
 
299
324
  ---
300
325
 
@@ -366,11 +391,9 @@ npx securenow firewall test-ip 1.2.3.4
366
391
 
367
392
  **Check 2:** Are you behind a proxy? The firewall needs to see the real client IP. Set `SECURENOW_TRUSTED_PROXIES` to your proxy's IP.
368
393
 
369
- **Check 3:** Is the sync interval too long? Reduce it:
394
+ **Check 3:** Wait 10-15 seconds for version-based propagation. The version check interval defaults to 10 seconds.
370
395
 
371
- ```bash
372
- SECURENOW_FIREWALL_SYNC_INTERVAL=10
373
- ```
396
+ **Check 4:** Using PM2? Make sure `node_args: '-r securenow/register'` is in your `ecosystem.config.cjs`. Without it, PM2 restarts skip the SDK entirely.
374
397
 
375
398
  ### iptables Layer Not Working
376
399
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "securenow",
3
- "version": "5.14.0",
3
+ "version": "5.15.0",
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",
@@ -131,7 +131,9 @@
131
131
  "docs/",
132
132
  "README.md",
133
133
  "NPM_README.md",
134
- "CONSUMING-APPS-GUIDE.md"
134
+ "CONSUMING-APPS-GUIDE.md",
135
+ "SKILL-CLI.md",
136
+ "SKILL-API.md"
135
137
  ],
136
138
  "dependencies": {
137
139
  "@opentelemetry/api": "1.7.0",