securenow 8.11.2 → 8.11.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/SKILL-CLI.md +623 -632
- package/TELEMETRY-SQL.md +6 -1
- package/cidr.js +83 -83
- package/cli/client.js +102 -102
- package/cli/diagnostics.js +4 -0
- package/cli/firewall.js +141 -141
- package/cli/fp.js +638 -638
- package/cli/monitor.js +398 -398
- package/cli/run.js +132 -132
- package/cli/security.js +1866 -1856
- package/cli/ui.js +374 -374
- package/cli.js +923 -922
- package/firewall-cloud.js +202 -202
- package/firewall-iptables.js +139 -139
- package/firewall-only.js +46 -46
- package/firewall-tcp.js +74 -74
- package/firewall.js +1470 -1470
- package/mcp/catalog.js +2358 -2346
- package/nextjs-auto-capture.d.ts +29 -29
- package/nextjs-auto-capture.js +273 -273
- package/nextjs-middleware.d.ts +57 -57
- package/nextjs-middleware.js +267 -267
- package/nextjs-webpack-config.js +79 -79
- package/nextjs-wrapper.d.ts +95 -95
- package/nextjs-wrapper.js +233 -233
- package/nuxt.mjs +74 -74
- package/package.json +1 -1
- package/register.d.ts +42 -42
- package/register.js +44 -44
- package/resolve-ip.js +13 -13
- package/telemetry-schema.json +3 -1
- package/tracing.js +853 -853
package/SKILL-CLI.md
CHANGED
|
@@ -1,255 +1,255 @@
|
|
|
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@latest
|
|
13
|
-
npx securenow <command>
|
|
14
|
-
```
|
|
15
|
-
|
|
16
|
-
**Full parity with the SDK:** every capability the `securenow` Node SDK exposes has a CLI counterpart — redaction, CIDR matching, log/span emission, firewall preload, config inspection. If you can do it in code, you can do it from the terminal.
|
|
17
|
-
|
|
18
|
-
**MCP parity (v8.0+):** the same package also ships a local stdio MCP server for Codex, Claude, and other MCP clients:
|
|
19
|
-
|
|
20
|
-
```bash
|
|
21
|
-
npx securenow login
|
|
22
|
-
codex mcp add securenow -- npx securenow mcp
|
|
23
|
-
# or
|
|
24
|
-
npx -p securenow securenow-mcp
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
The MCP server reads admin/control-plane auth from `.securenow/admin.json` and SDK runtime app credentials from `.securenow/runtime.json`, with legacy `.securenow/credentials.json` still supported. Admin/global tools use admin auth; runtime-scoped read tools can use the runtime API key where its scopes allow it. Write tools require `confirm:true` plus a reason.
|
|
28
|
-
|
|
29
|
-
### Authenticate
|
|
30
|
-
|
|
31
|
-
```bash
|
|
32
|
-
securenow login # friendly flow: admin auth + app runtime connection
|
|
33
|
-
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
34
|
-
securenow app connect # app/runtime SDK connection only
|
|
35
|
-
securenow admin login --token <JWT> # headless / CI admin auth
|
|
36
|
-
securenow whoami # verify both admin auth and runtime app status
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
**Two-lane credentials (v8.0+):** admin/control-plane auth lives in `.securenow/admin.json`; SDK runtime app config and the runtime API key live in `.securenow/runtime.json`. `securenow login` can run both lanes for onboarding, but `securenow admin login` never replaces runtime app config and `securenow app connect` never replaces admin auth. Legacy combined `.securenow/credentials.json` files are still read.
|
|
40
|
-
|
|
41
|
-
**Zero-config runtime flow:** the browser step lets the user pick (or create) an app. The CLI stores the app's **key (UUID)** and **name** in `.securenow/runtime.json`. The SDK sends traces/logs to the default SecureNow ingestion gateway, which routes by app key, so no env vars or per-instance collector URLs are required for local dev or production.
|
|
42
|
-
|
|
43
|
-
**Default-on security (v8.0+):** after picking or creating the app, `securenow app connect` turns on that app's firewall toggle, mints a runtime API key with `traces:write + logs:write + firewall:read + blocklist:read + allowlist:read` scopes, and writes it into `.securenow/runtime.json`. Traces, logs, POST body capture, multipart metadata capture, and the firewall are enabled by default. No `SECURENOW_API_KEY` env var is needed. To add or rotate a key later without re-running app connect, use `securenow api-key create` or `securenow api-key set snk_live_...` (see [API Key Management](#api-key-management) below).
|
|
44
|
-
|
|
45
|
-
Runtime credentials resolve in order: project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Runtime config is credentials-json based; environment-variable fallbacks are not supported.
|
|
46
|
-
|
|
47
|
-
The **runtime API key** should live in runtime credentials as `apiKey`; it authenticates telemetry ingestion and firewall sync.
|
|
48
|
-
|
|
49
|
-
For CI / Docker / production, use `securenow credentials runtime --env production` to generate a tokenless runtime file, then mount/copy it as `.securenow/credentials.json`. Since v7.7.2, mounting the generated `.securenow/credentials.production.json` filename directly also works when `credentials.json` is absent.
|
|
50
|
-
|
|
51
|
-
**Environment model:** use one SecureNow app key for local, preview, staging, and production. The credentials field `config.runtime.deploymentEnvironment` separates traces/logs/firewall/forensics by environment. CLI security commands default to `production`; pass `--env local`, `--env staging`, or `--env all` only when that scope is intentional.
|
|
52
|
-
|
|
53
|
-
### Integrate With Your App
|
|
54
|
-
|
|
55
|
-
The CLI can also instrument any Node.js app at launch — no code changes:
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
# Express, Fastify, NestJS, Koa, Hapi, raw Node.js
|
|
59
|
-
securenow run src/index.js
|
|
60
|
-
|
|
61
|
-
# Or via the Node preload flag
|
|
62
|
-
node -r securenow/register src/index.js
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
For Next.js, run the interactive scaffolding:
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
securenow login
|
|
69
|
-
securenow init
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
This auto-detects your framework, creates the necessary `instrumentation.ts` and `next.config.js` changes, and reuses the app, instance, and runtime API key written by login or `app connect` to `.securenow/runtime.json`.
|
|
73
|
-
|
|
74
|
-
### Install This Skill in Cursor
|
|
75
|
-
|
|
76
|
-
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.
|
|
77
|
-
|
|
78
|
-
## Configuration
|
|
79
|
-
|
|
80
|
-
Config lives in `~/.securenow/` (global) and optionally `.securenow/` (per-project):
|
|
81
|
-
|
|
82
|
-
| File | Content |
|
|
83
|
-
|------|---------|
|
|
84
|
-
| `~/.securenow/config.json` | `apiUrl`, `appUrl`, `defaultApp`, `output` |
|
|
85
|
-
| `~/.securenow/admin.json` | `token`, `email`, `expiresAt` for global admin/control-plane CLI and MCP auth |
|
|
86
|
-
| `~/.securenow/runtime.json` | `apiKey`, `app`, `config` for global SDK runtime |
|
|
87
|
-
| `.securenow/admin.json` | `token`, `email`, `expiresAt` for project-local admin/control-plane CLI and MCP auth |
|
|
88
|
-
| `.securenow/runtime.json` | `apiKey`, `app`, `config`, `_securenow.explanations` for project-local SDK runtime |
|
|
89
|
-
| `.securenow/credentials.json` | Legacy combined credentials; still read for backward compatibility |
|
|
90
|
-
| `.securenow/credentials.<environment>.json` | Tokenless runtime credentials generated by `securenow credentials runtime --env <environment>`; read in a fixed order, not selected from env vars |
|
|
91
|
-
|
|
92
|
-
**Credential resolution order:** runtime config resolves from project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Environment-variable fallbacks are not supported.
|
|
93
|
-
|
|
94
|
-
**Runtime API key resolution (v8.0+):** project `.securenow/runtime.json` -> legacy project credentials -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global runtime credentials -> legacy global credentials -> global named runtime credentials. Use `securenow app connect` for runtime setup or `securenow api-key set` to rotate a key without touching admin auth or env vars.
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
securenow config set apiUrl https://api.securenow.ai
|
|
98
|
-
securenow config set defaultApp my-app-key
|
|
99
|
-
securenow config get # show all
|
|
100
|
-
securenow config get defaultApp # show one
|
|
101
|
-
securenow config path # print file paths + active auth source
|
|
102
|
-
```
|
|
103
|
-
|
|
104
|
-
Legacy CLI overrides still exist for operator automation, but runtime SDK config should stay in the credentials file.
|
|
105
|
-
|
|
106
|
-
## Global Flags
|
|
107
|
-
|
|
108
|
-
| Flag | Short | Effect |
|
|
109
|
-
|------|-------|--------|
|
|
110
|
-
| `--json` | `-j` | JSON output (pipe-friendly) |
|
|
111
|
-
| `--help` | | Show help for any command |
|
|
112
|
-
| `--verbose` | `-v` | Verbose output |
|
|
113
|
-
| `--force` | `-f` | Skip confirmations |
|
|
114
|
-
| `--yes` | `-y` | Auto-confirm prompts |
|
|
115
|
-
|
|
116
|
-
SecureNow-specific environment overrides are not supported; use `.securenow/runtime.json`, `.securenow/admin.json`, or `securenow config set`.
|
|
117
|
-
|
|
118
|
-
---
|
|
119
|
-
|
|
120
|
-
## Command Reference
|
|
121
|
-
|
|
122
|
-
### Run — Instrument Any Node.js App
|
|
123
|
-
|
|
124
|
-
```bash
|
|
125
|
-
securenow run <script> # auto-detect CJS/ESM, inject OTel preload
|
|
126
|
-
securenow run --watch src/index.js # pass Node flags through
|
|
127
|
-
securenow run --inspect src/server.js --port 3000
|
|
128
|
-
securenow run --firewall-only app.js # preload firewall only (no tracing overhead)
|
|
129
|
-
securenow src/index.js # shorthand — auto-detected as "run"
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
Spawns `node --require securenow/register [--import otel/hook.mjs] <script>`. ESM detection uses nearest `package.json` `"type"` field or `.mjs`/`.cjs` extension. With `--firewall-only`, uses `securenow/firewall-only` instead (credentials-file firewall, no OpenTelemetry).
|
|
133
|
-
|
|
134
|
-
### Authentication
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
securenow login # friendly flow: admin auth + app runtime connection
|
|
138
|
-
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
139
|
-
securenow admin login --token <JWT> # headless / CI admin auth
|
|
140
|
-
securenow app connect # app/runtime SDK connection only
|
|
141
|
-
securenow logout # clear admin auth; runtime app config remains
|
|
142
|
-
securenow logout --global # clear global admin auth only
|
|
143
|
-
securenow whoami # show admin auth and runtime app status separately
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
### Applications
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
securenow apps # list all apps (default subcommand)
|
|
150
|
-
securenow apps list # same as above
|
|
151
|
-
securenow apps create <name> [--hosts h1,h2] [--instance <id>] # interactive instance picker
|
|
152
|
-
securenow apps info <id> # show app details
|
|
153
|
-
securenow apps delete <id> [--force] # delete an app
|
|
154
|
-
securenow apps default <app-key> # set default app for all commands
|
|
155
|
-
securenow apps discover [appId] [--domain example.com] # discover subdomains, add as apps
|
|
156
|
-
securenow apps scan [--yes] # scan all app domains for new subdomains
|
|
157
|
-
```
|
|
158
|
-
|
|
159
|
-
### API Key Management
|
|
160
|
-
|
|
161
|
-
Manage the runtime API key stored in runtime credentials. Since v8.0 the app runtime flow writes app-scoped `snk_live_...` keys to `.securenow/runtime.json` by default, so no env var is required for local dev.
|
|
162
|
-
|
|
163
|
-
```bash
|
|
164
|
-
securenow api-key create --name "CLI runtime" # mint + save a current-app runtime key
|
|
165
|
-
securenow api-key create --app <key-or-id> # mint + save a runtime key scoped to another app
|
|
166
|
-
securenow api-key set snk_live_xxxxxxxxxx # save to project ./.securenow/ (default)
|
|
167
|
-
securenow api-key set snk_live_xxx --global # save to ~/.securenow/ instead
|
|
168
|
-
securenow api-key show # print the masked current key + its source
|
|
169
|
-
securenow api-key clear # remove just the API key (keeps session/app)
|
|
170
|
-
securenow api-key clear --global # same, but from the global file
|
|
171
|
-
securenow credentials runtime --env production # write .securenow/credentials.production.json for production secret-file deploys
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
The key must start with `snk_live_`. `securenow app connect` writes the key automatically; use `api-key create` when you have admin auth but no runtime key yet, or `api-key set` when you already have a key from the dashboard. `api-key create` 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 with `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, and `allowlist:read`, then stores the one-time plaintext key as `apiKey`.
|
|
175
|
-
|
|
176
|
-
### Init — Project Setup
|
|
177
|
-
|
|
178
|
-
```bash
|
|
179
|
-
securenow init [--env local] [--key <API_KEY>]
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
|
|
183
|
-
- **Credentials**: ensures `.securenow/runtime.json` exists with secure defaults and explanations
|
|
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
|
-
- **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
|
-
- **Nuxt**: tells you to add `securenow/nuxt` to modules
|
|
187
|
-
- **Node/Express/etc.**: suggests adding `-r securenow/register` to start script
|
|
188
|
-
- Reuses `.securenow/runtime.json` written by login/app connect; production should mount/copy the tokenless runtime file generated by `securenow credentials runtime --env production`
|
|
189
|
-
|
|
190
|
-
### Dashboard & Status
|
|
191
|
-
|
|
192
|
-
```bash
|
|
193
|
-
securenow status [--app <key>] [--env local|production|all] # dashboard overview
|
|
194
|
-
securenow analytics [--app <key>] # response analytics
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
### Traces
|
|
200
|
-
|
|
201
|
-
```bash
|
|
202
|
-
securenow traces [--app <key>] [--env production] [--limit N] [--start ISO] [--end ISO]
|
|
203
|
-
securenow traces list --app my-app --env production --limit 50
|
|
204
|
-
securenow traces show <traceId> --env production # full trace detail with spans
|
|
205
|
-
securenow traces analyze <traceId> --env production # AI-powered trace analysis
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Logs
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
securenow logs [--app <key>] [--env production] [--limit N] [--minutes M] [--level error|warn|info]
|
|
212
|
-
securenow logs list --app my-app --env production --minutes 30 --level error
|
|
213
|
-
securenow logs trace <traceId> --env production # logs correlated to a specific trace
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Notifications
|
|
217
|
-
|
|
218
|
-
```bash
|
|
219
|
-
securenow notifications [--limit N] [--page P]
|
|
220
|
-
securenow notifications list --limit 20
|
|
221
|
-
securenow notifications read <id> # mark one as read
|
|
222
|
-
securenow notifications read-all # mark all as read
|
|
223
|
-
securenow notifications unread # unread count
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### Human Actions — AI-Prepared Decision Queue
|
|
227
|
-
|
|
228
|
-
Use this for the same work shown in **Requires Human**: AI has already grouped alerts, fetched traces, built a report, and left a final Block IP or False Positive decision.
|
|
229
|
-
|
|
230
|
-
```bash
|
|
231
|
-
securenow human # list human decisions, most urgent first
|
|
232
|
-
securenow human list --limit 20
|
|
233
|
-
securenow human show 1 # inspect row 1 with AI report, investigation steps, proofs, trace links
|
|
234
|
-
securenow human block 1 --yes --reason "AI evidence confirmed malicious"
|
|
235
|
-
securenow human fp 1 --yes --reason "Scoped false positive after evidence review"
|
|
236
|
-
securenow human action 1 --status rejected --yes --reason "Tuning guard is too broad"
|
|
237
|
-
securenow human prompt 1 # print a Codex/Claude MCP prompt for this row
|
|
238
|
-
securenow human work --limit 10 # list queue + print MCP runbook for deep queue work
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
MCP parity:
|
|
242
|
-
|
|
243
|
-
- `securenow_human_actions_list`
|
|
244
|
-
- `securenow_notifications_get`
|
|
245
|
-
- `securenow_human_action_report`
|
|
246
|
-
- `securenow_human_action_block`
|
|
247
|
-
- `securenow_human_action_false_positive`
|
|
248
|
-
- `securenow_human_case_action_update`
|
|
249
|
-
- prompts: `investigate_human_action_row`, `work_human_actions`
|
|
250
|
-
|
|
251
|
-
Write tools still require `confirm:true` plus a reason. False positives should stay restrictive to the app, alert rule, path, method/status, user-agent, body pattern, or other exact evidence the AI report supports. Notification IP investigations can include `metadata.matchedSubdetectors`; prefer that exact field over inferring which subdetector fired from the title or sample body.
|
|
252
|
-
|
|
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@latest
|
|
13
|
+
npx securenow <command>
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Full parity with the SDK:** every capability the `securenow` Node SDK exposes has a CLI counterpart — redaction, CIDR matching, log/span emission, firewall preload, config inspection. If you can do it in code, you can do it from the terminal.
|
|
17
|
+
|
|
18
|
+
**MCP parity (v8.0+):** the same package also ships a local stdio MCP server for Codex, Claude, and other MCP clients:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npx securenow login
|
|
22
|
+
codex mcp add securenow -- npx securenow mcp
|
|
23
|
+
# or
|
|
24
|
+
npx -p securenow securenow-mcp
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The MCP server reads admin/control-plane auth from `.securenow/admin.json` and SDK runtime app credentials from `.securenow/runtime.json`, with legacy `.securenow/credentials.json` still supported. Admin/global tools use admin auth; runtime-scoped read tools can use the runtime API key where its scopes allow it. Write tools require `confirm:true` plus a reason.
|
|
28
|
+
|
|
29
|
+
### Authenticate
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
securenow login # friendly flow: admin auth + app runtime connection
|
|
33
|
+
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
34
|
+
securenow app connect # app/runtime SDK connection only
|
|
35
|
+
securenow admin login --token <JWT> # headless / CI admin auth
|
|
36
|
+
securenow whoami # verify both admin auth and runtime app status
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
**Two-lane credentials (v8.0+):** admin/control-plane auth lives in `.securenow/admin.json`; SDK runtime app config and the runtime API key live in `.securenow/runtime.json`. `securenow login` can run both lanes for onboarding, but `securenow admin login` never replaces runtime app config and `securenow app connect` never replaces admin auth. Legacy combined `.securenow/credentials.json` files are still read.
|
|
40
|
+
|
|
41
|
+
**Zero-config runtime flow:** the browser step lets the user pick (or create) an app. The CLI stores the app's **key (UUID)** and **name** in `.securenow/runtime.json`. The SDK sends traces/logs to the default SecureNow ingestion gateway, which routes by app key, so no env vars or per-instance collector URLs are required for local dev or production.
|
|
42
|
+
|
|
43
|
+
**Default-on security (v8.0+):** after picking or creating the app, `securenow app connect` turns on that app's firewall toggle, mints a runtime API key with `traces:write + logs:write + firewall:read + blocklist:read + allowlist:read` scopes, and writes it into `.securenow/runtime.json`. Traces, logs, POST body capture, multipart metadata capture, and the firewall are enabled by default. No `SECURENOW_API_KEY` env var is needed. To add or rotate a key later without re-running app connect, use `securenow api-key create` or `securenow api-key set snk_live_...` (see [API Key Management](#api-key-management) below).
|
|
44
|
+
|
|
45
|
+
Runtime credentials resolve in order: project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Runtime config is credentials-json based; environment-variable fallbacks are not supported.
|
|
46
|
+
|
|
47
|
+
The **runtime API key** should live in runtime credentials as `apiKey`; it authenticates telemetry ingestion and firewall sync.
|
|
48
|
+
|
|
49
|
+
For CI / Docker / production, use `securenow credentials runtime --env production` to generate a tokenless runtime file, then mount/copy it as `.securenow/credentials.json`. Since v7.7.2, mounting the generated `.securenow/credentials.production.json` filename directly also works when `credentials.json` is absent.
|
|
50
|
+
|
|
51
|
+
**Environment model:** use one SecureNow app key for local, preview, staging, and production. The credentials field `config.runtime.deploymentEnvironment` separates traces/logs/firewall/forensics by environment. CLI security commands default to `production`; pass `--env local`, `--env staging`, or `--env all` only when that scope is intentional.
|
|
52
|
+
|
|
53
|
+
### Integrate With Your App
|
|
54
|
+
|
|
55
|
+
The CLI can also instrument any Node.js app at launch — no code changes:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Express, Fastify, NestJS, Koa, Hapi, raw Node.js
|
|
59
|
+
securenow run src/index.js
|
|
60
|
+
|
|
61
|
+
# Or via the Node preload flag
|
|
62
|
+
node -r securenow/register src/index.js
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
For Next.js, run the interactive scaffolding:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
securenow login
|
|
69
|
+
securenow init
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
This auto-detects your framework, creates the necessary `instrumentation.ts` and `next.config.js` changes, and reuses the app, instance, and runtime API key written by login or `app connect` to `.securenow/runtime.json`.
|
|
73
|
+
|
|
74
|
+
### Install This Skill in Cursor
|
|
75
|
+
|
|
76
|
+
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.
|
|
77
|
+
|
|
78
|
+
## Configuration
|
|
79
|
+
|
|
80
|
+
Config lives in `~/.securenow/` (global) and optionally `.securenow/` (per-project):
|
|
81
|
+
|
|
82
|
+
| File | Content |
|
|
83
|
+
|------|---------|
|
|
84
|
+
| `~/.securenow/config.json` | `apiUrl`, `appUrl`, `defaultApp`, `output` |
|
|
85
|
+
| `~/.securenow/admin.json` | `token`, `email`, `expiresAt` for global admin/control-plane CLI and MCP auth |
|
|
86
|
+
| `~/.securenow/runtime.json` | `apiKey`, `app`, `config` for global SDK runtime |
|
|
87
|
+
| `.securenow/admin.json` | `token`, `email`, `expiresAt` for project-local admin/control-plane CLI and MCP auth |
|
|
88
|
+
| `.securenow/runtime.json` | `apiKey`, `app`, `config`, `_securenow.explanations` for project-local SDK runtime |
|
|
89
|
+
| `.securenow/credentials.json` | Legacy combined credentials; still read for backward compatibility |
|
|
90
|
+
| `.securenow/credentials.<environment>.json` | Tokenless runtime credentials generated by `securenow credentials runtime --env <environment>`; read in a fixed order, not selected from env vars |
|
|
91
|
+
|
|
92
|
+
**Credential resolution order:** runtime config resolves from project `.securenow/runtime.json` -> legacy project `.securenow/credentials.json` -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global `.securenow/runtime.json` -> legacy global credentials -> global named runtime credentials. Admin auth resolves from `admin.json` first, then legacy `credentials.json`. Environment-variable fallbacks are not supported.
|
|
93
|
+
|
|
94
|
+
**Runtime API key resolution (v8.0+):** project `.securenow/runtime.json` -> legacy project credentials -> project named runtime credentials in the fixed staging/production/preview/local/test/development/dev/prod order -> global runtime credentials -> legacy global credentials -> global named runtime credentials. Use `securenow app connect` for runtime setup or `securenow api-key set` to rotate a key without touching admin auth or env vars.
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
securenow config set apiUrl https://api.securenow.ai
|
|
98
|
+
securenow config set defaultApp my-app-key
|
|
99
|
+
securenow config get # show all
|
|
100
|
+
securenow config get defaultApp # show one
|
|
101
|
+
securenow config path # print file paths + active auth source
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Legacy CLI overrides still exist for operator automation, but runtime SDK config should stay in the credentials file.
|
|
105
|
+
|
|
106
|
+
## Global Flags
|
|
107
|
+
|
|
108
|
+
| Flag | Short | Effect |
|
|
109
|
+
|------|-------|--------|
|
|
110
|
+
| `--json` | `-j` | JSON output (pipe-friendly) |
|
|
111
|
+
| `--help` | | Show help for any command |
|
|
112
|
+
| `--verbose` | `-v` | Verbose output |
|
|
113
|
+
| `--force` | `-f` | Skip confirmations |
|
|
114
|
+
| `--yes` | `-y` | Auto-confirm prompts |
|
|
115
|
+
|
|
116
|
+
SecureNow-specific environment overrides are not supported; use `.securenow/runtime.json`, `.securenow/admin.json`, or `securenow config set`.
|
|
117
|
+
|
|
118
|
+
---
|
|
119
|
+
|
|
120
|
+
## Command Reference
|
|
121
|
+
|
|
122
|
+
### Run — Instrument Any Node.js App
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
securenow run <script> # auto-detect CJS/ESM, inject OTel preload
|
|
126
|
+
securenow run --watch src/index.js # pass Node flags through
|
|
127
|
+
securenow run --inspect src/server.js --port 3000
|
|
128
|
+
securenow run --firewall-only app.js # preload firewall only (no tracing overhead)
|
|
129
|
+
securenow src/index.js # shorthand — auto-detected as "run"
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Spawns `node --require securenow/register [--import otel/hook.mjs] <script>`. ESM detection uses nearest `package.json` `"type"` field or `.mjs`/`.cjs` extension. With `--firewall-only`, uses `securenow/firewall-only` instead (credentials-file firewall, no OpenTelemetry).
|
|
133
|
+
|
|
134
|
+
### Authentication
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
securenow login # friendly flow: admin auth + app runtime connection
|
|
138
|
+
securenow admin login # admin/control-plane CLI and MCP auth only
|
|
139
|
+
securenow admin login --token <JWT> # headless / CI admin auth
|
|
140
|
+
securenow app connect # app/runtime SDK connection only
|
|
141
|
+
securenow logout # clear admin auth; runtime app config remains
|
|
142
|
+
securenow logout --global # clear global admin auth only
|
|
143
|
+
securenow whoami # show admin auth and runtime app status separately
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
### Applications
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
securenow apps # list all apps (default subcommand)
|
|
150
|
+
securenow apps list # same as above
|
|
151
|
+
securenow apps create <name> [--hosts h1,h2] [--instance <id>] # interactive instance picker
|
|
152
|
+
securenow apps info <id> # show app details
|
|
153
|
+
securenow apps delete <id> [--force] # delete an app
|
|
154
|
+
securenow apps default <app-key> # set default app for all commands
|
|
155
|
+
securenow apps discover [appId] [--domain example.com] # discover subdomains, add as apps
|
|
156
|
+
securenow apps scan [--yes] # scan all app domains for new subdomains
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### API Key Management
|
|
160
|
+
|
|
161
|
+
Manage the runtime API key stored in runtime credentials. Since v8.0 the app runtime flow writes app-scoped `snk_live_...` keys to `.securenow/runtime.json` by default, so no env var is required for local dev.
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
securenow api-key create --name "CLI runtime" # mint + save a current-app runtime key
|
|
165
|
+
securenow api-key create --app <key-or-id> # mint + save a runtime key scoped to another app
|
|
166
|
+
securenow api-key set snk_live_xxxxxxxxxx # save to project ./.securenow/ (default)
|
|
167
|
+
securenow api-key set snk_live_xxx --global # save to ~/.securenow/ instead
|
|
168
|
+
securenow api-key show # print the masked current key + its source
|
|
169
|
+
securenow api-key clear # remove just the API key (keeps session/app)
|
|
170
|
+
securenow api-key clear --global # same, but from the global file
|
|
171
|
+
securenow credentials runtime --env production # write .securenow/credentials.production.json for production secret-file deploys
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
The key must start with `snk_live_`. `securenow app connect` writes the key automatically; use `api-key create` when you have admin auth but no runtime key yet, or `api-key set` when you already have a key from the dashboard. `api-key create` 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 with `traces:write`, `logs:write`, `firewall:read`, `blocklist:read`, and `allowlist:read`, then stores the one-time plaintext key as `apiKey`.
|
|
175
|
+
|
|
176
|
+
### Init — Project Setup
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
securenow init [--env local] [--key <API_KEY>]
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Auto-detects framework (Next.js, Nuxt, Express, Fastify, Koa, Hapi, Node) from `package.json`. Then:
|
|
183
|
+
- **Credentials**: ensures `.securenow/runtime.json` exists with secure defaults and explanations
|
|
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
|
+
- **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
|
+
- **Nuxt**: tells you to add `securenow/nuxt` to modules
|
|
187
|
+
- **Node/Express/etc.**: suggests adding `-r securenow/register` to start script
|
|
188
|
+
- Reuses `.securenow/runtime.json` written by login/app connect; production should mount/copy the tokenless runtime file generated by `securenow credentials runtime --env production`
|
|
189
|
+
|
|
190
|
+
### Dashboard & Status
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
securenow status [--app <key>] [--env local|production|all] # dashboard overview
|
|
194
|
+
securenow analytics [--app <key>] # response analytics
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
### Traces
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
securenow traces [--app <key>] [--env production] [--limit N] [--start ISO] [--end ISO]
|
|
203
|
+
securenow traces list --app my-app --env production --limit 50
|
|
204
|
+
securenow traces show <traceId> --env production # full trace detail with spans
|
|
205
|
+
securenow traces analyze <traceId> --env production # AI-powered trace analysis
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Logs
|
|
209
|
+
|
|
210
|
+
```bash
|
|
211
|
+
securenow logs [--app <key>] [--env production] [--limit N] [--minutes M] [--level error|warn|info]
|
|
212
|
+
securenow logs list --app my-app --env production --minutes 30 --level error
|
|
213
|
+
securenow logs trace <traceId> --env production # logs correlated to a specific trace
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### Notifications
|
|
217
|
+
|
|
218
|
+
```bash
|
|
219
|
+
securenow notifications [--limit N] [--page P]
|
|
220
|
+
securenow notifications list --limit 20
|
|
221
|
+
securenow notifications read <id> # mark one as read
|
|
222
|
+
securenow notifications read-all # mark all as read
|
|
223
|
+
securenow notifications unread # unread count
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### Human Actions — AI-Prepared Decision Queue
|
|
227
|
+
|
|
228
|
+
Use this for the same work shown in **Requires Human**: AI has already grouped alerts, fetched traces, built a report, and left a final Block IP or False Positive decision.
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
securenow human # list human decisions, most urgent first
|
|
232
|
+
securenow human list --limit 20
|
|
233
|
+
securenow human show 1 # inspect row 1 with AI report, investigation steps, proofs, trace links
|
|
234
|
+
securenow human block 1 --yes --reason "AI evidence confirmed malicious"
|
|
235
|
+
securenow human fp 1 --yes --reason "Scoped false positive after evidence review"
|
|
236
|
+
securenow human action 1 --status rejected --yes --reason "Tuning guard is too broad"
|
|
237
|
+
securenow human prompt 1 # print a Codex/Claude MCP prompt for this row
|
|
238
|
+
securenow human work --limit 10 # list queue + print MCP runbook for deep queue work
|
|
239
|
+
```
|
|
240
|
+
|
|
241
|
+
MCP parity:
|
|
242
|
+
|
|
243
|
+
- `securenow_human_actions_list`
|
|
244
|
+
- `securenow_notifications_get`
|
|
245
|
+
- `securenow_human_action_report`
|
|
246
|
+
- `securenow_human_action_block`
|
|
247
|
+
- `securenow_human_action_false_positive`
|
|
248
|
+
- `securenow_human_case_action_update`
|
|
249
|
+
- prompts: `investigate_human_action_row`, `work_human_actions`
|
|
250
|
+
|
|
251
|
+
Write tools still require `confirm:true` plus a reason. False positives should stay restrictive to the app, alert rule, path, method/status, user-agent, body pattern, or other exact evidence the AI report supports. Notification IP investigations can include `metadata.matchedSubdetectors`; prefer that exact field over inferring which subdetector fired from the title or sample body.
|
|
252
|
+
|
|
253
253
|
### Alerts
|
|
254
254
|
|
|
255
255
|
Before authoring any alert SQL, load the contract shipped by the installed package and compare
|
|
@@ -271,385 +271,376 @@ its fields were observed and `alerts rules validate` succeeds. Otherwise label i
|
|
|
271
271
|
`NEEDS_INSTRUMENTATION`, `NEEDS_BASELINE`, or `NEEDS_CUSTOMER_DECISION` as appropriate.
|
|
272
272
|
|
|
273
273
|
```bash
|
|
274
|
-
securenow alerts # list alert rules (default)
|
|
275
|
-
securenow alerts rules # list alert rules (columns: Status, Applications, Schedule)
|
|
276
|
-
securenow alerts rules validate \ # dry-run a candidate query BEFORE creating any rule
|
|
277
|
-
--sql @rule.sql --app <key> # no rule id needed — auto-hosts on an existing (system) rule
|
|
278
|
-
securenow alerts rules create \ # create a custom detection rule from inline SQL
|
|
279
|
-
--name "Auth: magic-link brute force" \
|
|
280
|
-
--sql @rule.sql \ # SQL, @file, or - for stdin; scope apps with __USER_APP_KEYS__
|
|
281
|
-
--apps key1,key2 \ # or --applications-all
|
|
282
|
-
--severity high --schedule "*/15 * * * *" \
|
|
283
|
-
--nlp "single IP flooding /api/auth/signin or /api/auth/callback"
|
|
284
|
-
# create auto dry-runs + rolls back (deletes) on query failure; --no-validate to skip
|
|
285
|
-
securenow alerts rules show <id> # one rule; JSON: --json
|
|
286
|
-
securenow alerts rules set-sql <id> --sql @new.sql # replace a CUSTOM rule's SQL in place (alias: update <id> --sql)
|
|
287
|
-
securenow alerts rules delete <id> --yes # delete a custom rule (system rules: disable instead)
|
|
288
|
-
securenow alerts rules update <id> --applications-all # all current & future apps
|
|
289
|
-
securenow alerts rules update <id> --apps key1,key2 # explicit app keys only
|
|
290
|
-
securenow alerts rules test <id> --mode dry_run --wait # validate an existing rule's query
|
|
291
|
-
securenow alerts rules dry-run-query <id> --sql @candidate.sql --app <key> --wait # candidate test against a specific host rule
|
|
292
|
-
securenow alerts rules tune-query <id> --sql @candidate.sql --reason "Preserve exploit detector, remove benign broad match" --apply-globally --yes
|
|
293
|
-
securenow alerts rules exclusions <id> list # embedded rule exclusions
|
|
294
|
-
securenow alerts channels # list alert channels (Slack, email, etc.)
|
|
295
|
-
securenow alerts history [--limit N] # past triggered alerts
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
**Authoring loop that won't strand a broken rule:** `validate --sql @rule.sql --app <key>`
|
|
299
|
-
(dry-run before anything exists) → `create …` (which itself dry-runs and auto-rolls-back on
|
|
300
|
-
failure) → if you later need to fix it, `set-sql <id> --sql @rule.sql` (custom rules) or
|
|
301
|
-
`delete <id>`. Detection `.sql` files may start with `--`/`/* */` comments. Custom-rule SQL is
|
|
302
|
-
editable; **system**-rule SQL changes go through `tune-query … --apply-globally`. Pick the
|
|
303
|
-
right tenant-scope column per table: logs (`signoz_logs.distributed_logs_v2`) use
|
|
304
|
-
`resources_string['service.name'] IN (__USER_APP_KEYS__)`, traces
|
|
305
|
-
(`signoz_traces.distributed_signoz_index_v3`) use `` `resource_string_service$$name` IN (__USER_APP_KEYS__) ``.
|
|
306
|
-
|
|
307
|
-
`alerts rules create` flags: `--name` (required); one of `--sql <sql|@file|->` or `--query-mapping-id <id>`; one of `--apps k1,k2` or `--applications-all`; optional `--description`, `--nlp` (plain-English intent), `--category`, `--severity critical|high|medium|low`, `--schedule <cron>` (default `*/15 * * * *`), `--throttle-minutes N` / `--no-throttle`, `--execution-mode scheduled|instant|hybrid`, `--channel id1,id2` (defaults to your in-app SecureNow channel). Detection SQL must scope app keys via the `__USER_APP_KEYS__` placeholder and select an `ip` column for per-IP aggregation/remediation. Requires `alerts:write`.
|
|
308
|
-
|
|
309
|
-
MCP parity for noisy alert-rule reviews:
|
|
310
|
-
|
|
311
|
-
- `securenow_alert_rule_get`
|
|
312
|
-
- `securenow_alert_rule_candidate_test` dry-runs a full candidate SQL query without saving it.
|
|
313
|
-
- `securenow_alert_rule_test_result` polls the dry-run.
|
|
314
|
-
- `securenow_alert_rule_query_update` updates the shared public query mapping behind a system rule for all customer copies. It is admin-only, requires `confirm:true`, `applyGlobally:true`, `reason`, and SQL that keeps `__USER_APP_KEYS__` tenant scoping.
|
|
315
|
-
- `securenow_alert_rule_instant_update` patches Instant rule conditions/config with stale-write guards. Fetch the rule first, pass `expectedRuleVersion` plus `expectedCurrentInstantHash`, use operations such as `remove_condition` / `add_condition` / `update_condition`, and set `applyGlobally:true` for system rules. The API runs seeded before/after checks and returns benign samples removed plus attack samples still matching. If global tuning is denied, it returns a structured admin handoff with the exact patch and missing permission.
|
|
316
|
-
- `securenow_alert_rule_exclusion_add` remains the last-resort customer-specific path; it supports restrictive conditions plus `matchMode` and should not be used to hide a generic system-rule bug.
|
|
317
|
-
|
|
318
|
-
For system-rule tuning, dry-run the candidate SQL first for scheduled rules, or use `dryRun:true` on `securenow_alert_rule_instant_update` for Instant rules. Save only when the guard preserves attack detection. Good guards add exact exploit tokens, dangerous schemes, matched subdetectors, sensitive path/status evidence, malicious user agents, or repeat thresholds; bad guards simply suppress a noisy path.
|
|
319
|
-
|
|
320
|
-
---
|
|
321
|
-
|
|
322
|
-
### IP Intelligence
|
|
323
|
-
|
|
324
|
-
```bash
|
|
325
|
-
securenow ip <ip-address> # lookup (geo, ASN, threat score, reputation)
|
|
326
|
-
securenow ip lookup <ip-address> # same as above
|
|
327
|
-
securenow ip traces <ip-address> --env production # traces originating from this IP
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
### Forensics — Natural Language Security Queries
|
|
331
|
-
|
|
332
|
-
```bash
|
|
333
|
-
securenow forensics "show me all SQL injection attempts in the last 24h" --env production
|
|
334
|
-
securenow forensics query "top 10 IPs by blocked requests" --app my-app --env production
|
|
335
|
-
securenow forensics chat --app my-app --env production # interactive forensics chat session
|
|
336
|
-
securenow forensics library # view saved/template queries
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
securenow
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
securenow
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
allowlist
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
```
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
--
|
|
466
|
-
--
|
|
467
|
-
--
|
|
468
|
-
--
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
**
|
|
504
|
-
|
|
505
|
-
**
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
securenow test-span
|
|
536
|
-
securenow test-span "ci.smoke-test" # custom span name
|
|
537
|
-
```
|
|
538
|
-
|
|
539
|
-
Both commands use the default SecureNow ingestion gateway plus optional advanced `config.otel.*` overrides from `.securenow/runtime.json` or legacy runtime credentials, and return non-zero on HTTP errors so CI/cron can detect failures.
|
|
540
|
-
|
|
274
|
+
securenow alerts # list alert rules (default)
|
|
275
|
+
securenow alerts rules # list alert rules (columns: Status, Applications, Schedule)
|
|
276
|
+
securenow alerts rules validate \ # dry-run a candidate query BEFORE creating any rule
|
|
277
|
+
--sql @rule.sql --app <key> # no rule id needed — auto-hosts on an existing (system) rule
|
|
278
|
+
securenow alerts rules create \ # create a custom detection rule from inline SQL
|
|
279
|
+
--name "Auth: magic-link brute force" \
|
|
280
|
+
--sql @rule.sql \ # SQL, @file, or - for stdin; scope apps with __USER_APP_KEYS__
|
|
281
|
+
--apps key1,key2 \ # or --applications-all
|
|
282
|
+
--severity high --schedule "*/15 * * * *" \
|
|
283
|
+
--nlp "single IP flooding /api/auth/signin or /api/auth/callback"
|
|
284
|
+
# create auto dry-runs + rolls back (deletes) on query failure; --no-validate to skip
|
|
285
|
+
securenow alerts rules show <id> # one rule; JSON: --json
|
|
286
|
+
securenow alerts rules set-sql <id> --sql @new.sql # replace a CUSTOM rule's SQL in place (alias: update <id> --sql)
|
|
287
|
+
securenow alerts rules delete <id> --yes # delete a custom rule (system rules: disable instead)
|
|
288
|
+
securenow alerts rules update <id> --applications-all # all current & future apps
|
|
289
|
+
securenow alerts rules update <id> --apps key1,key2 # explicit app keys only
|
|
290
|
+
securenow alerts rules test <id> --mode dry_run --wait # validate an existing rule's query
|
|
291
|
+
securenow alerts rules dry-run-query <id> --sql @candidate.sql --app <key> --wait # candidate test against a specific host rule
|
|
292
|
+
securenow alerts rules tune-query <id> --sql @candidate.sql --reason "Preserve exploit detector, remove benign broad match" --apply-globally --yes
|
|
293
|
+
securenow alerts rules exclusions <id> list # embedded rule exclusions
|
|
294
|
+
securenow alerts channels # list alert channels (Slack, email, etc.)
|
|
295
|
+
securenow alerts history [--limit N] # past triggered alerts
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
**Authoring loop that won't strand a broken rule:** `validate --sql @rule.sql --app <key>`
|
|
299
|
+
(dry-run before anything exists) → `create …` (which itself dry-runs and auto-rolls-back on
|
|
300
|
+
failure) → if you later need to fix it, `set-sql <id> --sql @rule.sql` (custom rules) or
|
|
301
|
+
`delete <id>`. Detection `.sql` files may start with `--`/`/* */` comments. Custom-rule SQL is
|
|
302
|
+
editable; **system**-rule SQL changes go through `tune-query … --apply-globally`. Pick the
|
|
303
|
+
right tenant-scope column per table: logs (`signoz_logs.distributed_logs_v2`) use
|
|
304
|
+
`resources_string['service.name'] IN (__USER_APP_KEYS__)`, traces
|
|
305
|
+
(`signoz_traces.distributed_signoz_index_v3`) use `` `resource_string_service$$name` IN (__USER_APP_KEYS__) ``.
|
|
306
|
+
|
|
307
|
+
`alerts rules create` flags: `--name` (required); one of `--sql <sql|@file|->` or `--query-mapping-id <id>`; one of `--apps k1,k2` or `--applications-all`; optional `--description`, `--nlp` (plain-English intent), `--category`, `--severity critical|high|medium|low`, `--schedule <cron>` (default `*/15 * * * *`), `--throttle-minutes N` / `--no-throttle`, `--execution-mode scheduled|instant|hybrid`, `--channel id1,id2` (defaults to your in-app SecureNow channel). Detection SQL must scope app keys via the `__USER_APP_KEYS__` placeholder and select an `ip` column for per-IP aggregation/remediation. Requires `alerts:write`.
|
|
308
|
+
|
|
309
|
+
MCP parity for noisy alert-rule reviews:
|
|
310
|
+
|
|
311
|
+
- `securenow_alert_rule_get`
|
|
312
|
+
- `securenow_alert_rule_candidate_test` dry-runs a full candidate SQL query without saving it.
|
|
313
|
+
- `securenow_alert_rule_test_result` polls the dry-run.
|
|
314
|
+
- `securenow_alert_rule_query_update` updates the shared public query mapping behind a system rule for all customer copies. It is admin-only, requires `confirm:true`, `applyGlobally:true`, `reason`, and SQL that keeps `__USER_APP_KEYS__` tenant scoping.
|
|
315
|
+
- `securenow_alert_rule_instant_update` patches Instant rule conditions/config with stale-write guards. Fetch the rule first, pass `expectedRuleVersion` plus `expectedCurrentInstantHash`, use operations such as `remove_condition` / `add_condition` / `update_condition`, and set `applyGlobally:true` for system rules. The API runs seeded before/after checks and returns benign samples removed plus attack samples still matching. If global tuning is denied, it returns a structured admin handoff with the exact patch and missing permission.
|
|
316
|
+
- `securenow_alert_rule_exclusion_add` remains the last-resort customer-specific path; it supports restrictive conditions plus `matchMode` and should not be used to hide a generic system-rule bug.
|
|
317
|
+
|
|
318
|
+
For system-rule tuning, dry-run the candidate SQL first for scheduled rules, or use `dryRun:true` on `securenow_alert_rule_instant_update` for Instant rules. Save only when the guard preserves attack detection. Good guards add exact exploit tokens, dangerous schemes, matched subdetectors, sensitive path/status evidence, malicious user agents, or repeat thresholds; bad guards simply suppress a noisy path.
|
|
319
|
+
|
|
320
|
+
---
|
|
321
|
+
|
|
322
|
+
### IP Intelligence
|
|
323
|
+
|
|
324
|
+
```bash
|
|
325
|
+
securenow ip <ip-address> # lookup (geo, ASN, threat score, reputation)
|
|
326
|
+
securenow ip lookup <ip-address> # same as above
|
|
327
|
+
securenow ip traces <ip-address> --env production # traces originating from this IP
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
### Forensics — Natural Language Security Queries
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
securenow forensics "show me all SQL injection attempts in the last 24h" --env production
|
|
334
|
+
securenow forensics query "top 10 IPs by blocked requests" --app my-app --env production
|
|
335
|
+
securenow forensics chat --app my-app --env production # interactive forensics chat session
|
|
336
|
+
securenow forensics library # view saved/template queries
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
---
|
|
340
|
+
|
|
341
|
+
### Firewall
|
|
342
|
+
|
|
343
|
+
```bash
|
|
344
|
+
securenow firewall # show status (default)
|
|
345
|
+
securenow firewall status --app <key> --env production # app/env toggle, sync time, blocked count
|
|
346
|
+
securenow firewall test-ip <ip> --app <key> --env local # check if IP would be blocked
|
|
347
|
+
```
|
|
348
|
+
|
|
349
|
+
**Zero-config setup:** running `securenow app connect` enables the selected app's firewall toggle, auto-mints a runtime API key (scoped `traces:write + logs:write + firewall:read + blocklist:read + allowlist:read`), and writes it to `.securenow/runtime.json` after the app is selected. No `SECURENOW_API_KEY` env var needed. If the user already has a key, `securenow api-key set snk_live_...` achieves the same thing; if they only have admin auth, `securenow api-key create` mints and saves a fresh runtime key. See [the landing firewall page](https://securenow.ai/firewall) for an overview.
|
|
350
|
+
|
|
351
|
+
### Blocklist — Block Malicious IPs
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
securenow blocklist # list blocked IPs
|
|
355
|
+
securenow blocklist list
|
|
356
|
+
securenow blocklist add <ip> --app <key> --env production --reason "Brute force"
|
|
357
|
+
securenow blocklist add <ip> --route /admin* --mode prefix --method ALL --reason "Admin probing"
|
|
358
|
+
securenow blocklist unblock <id> --reason "False alarm after review"
|
|
359
|
+
securenow blocklist remove <id> # compatibility alias for unblock
|
|
360
|
+
securenow blocklist list --status removed # audit retained unblocks
|
|
361
|
+
securenow blocklist stats # block counts, top reasons
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
Scoped blocks use the same model as rate limits: `--route`/`--path`/`--pattern`
|
|
365
|
+
sets `pathPattern`, `--mode`/`--path-mode` chooses `prefix`, `exact`, or
|
|
366
|
+
`regex`, and `--method` limits enforcement to one HTTP method or `ALL`.
|
|
367
|
+
|
|
368
|
+
Unblock stops firewall enforcement but preserves the block report, history, and
|
|
369
|
+
unblock audit fields. Reblocking the same IP later creates a fresh active block
|
|
370
|
+
without erasing the previous investigation trail.
|
|
371
|
+
|
|
372
|
+
MCP exposes legacy pending-block cleanup separately from current Requires Human
|
|
373
|
+
work:
|
|
374
|
+
|
|
375
|
+
- `securenow_blocklist_unblock`
|
|
376
|
+
- `securenow_blocklist_remove` (compatibility alias for unblock)
|
|
377
|
+
- `securenow_blocklist_pending_list`
|
|
378
|
+
- `securenow_blocklist_pending_approve`
|
|
379
|
+
- `securenow_blocklist_pending_reject`
|
|
380
|
+
- `securenow_blocklist_pending_bulk_approve`
|
|
381
|
+
- `securenow_blocklist_pending_bulk_reject`
|
|
382
|
+
- prompt: `cleanup_legacy_pending_blocks`
|
|
383
|
+
|
|
384
|
+
### Rate Limits - Soft Remediation
|
|
385
|
+
|
|
386
|
+
```bash
|
|
387
|
+
securenow ratelimit list --env production
|
|
388
|
+
securenow ratelimit add 203.0.113.42 --route /api/login --limit 2 --window 1m --duration 24h
|
|
389
|
+
securenow ratelimit parse "rate limit 203.0.113.42 on POST /api/login to 2 attempts per minute"
|
|
390
|
+
securenow ratelimit from-text "rate limit /api/login for this IP to 2 attempts per minute for 24h" --yes
|
|
391
|
+
securenow ratelimit test 203.0.113.42 --path /api/login --method POST
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
MCP parity:
|
|
395
|
+
|
|
396
|
+
- `securenow_rate_limit_parse`
|
|
397
|
+
- `securenow_rate_limit_create_from_text`
|
|
398
|
+
|
|
399
|
+
### Automation Rules
|
|
400
|
+
|
|
401
|
+
```bash
|
|
402
|
+
securenow automation # list blocklist automation rules
|
|
403
|
+
securenow automation defaults --yes # ensure built-in default risk-score rules
|
|
404
|
+
securenow automation show <id>
|
|
405
|
+
securenow automation dry-run <id> --limit 500
|
|
406
|
+
securenow automation execute <id> --yes
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Built-in default automation is enabled by default for all apps/environments and
|
|
410
|
+
uses the canonical `riskScore`: 95-100 blocks for 7 days, 90-94 blocks for 72h,
|
|
411
|
+
85-89 blocks for 24h, and scores below 85 stay in investigation/review unless
|
|
412
|
+
the customer adds a stricter custom rule. Raw SecureNow IPDB confidence remains
|
|
413
|
+
supporting evidence, not the primary automation score.
|
|
414
|
+
|
|
415
|
+
### Allowlist — Restrict to Known IPs
|
|
416
|
+
|
|
417
|
+
Dangerous production mode: IP Allowlist is deny-by-default. Once any active
|
|
418
|
+
allowlist entry exists for an app/environment, only listed IPs can reach it and
|
|
419
|
+
all other IPs are blocked. Do not use allowlist to mark an IP trusted, suppress
|
|
420
|
+
false positives, or clean up investigations. Use `securenow trusted add` for
|
|
421
|
+
known-safe monitors, office/VPN traffic, or trusted bypass cases.
|
|
422
|
+
|
|
423
|
+
```bash
|
|
424
|
+
securenow allowlist # list allowed IPs
|
|
425
|
+
securenow allowlist list
|
|
426
|
+
securenow allowlist add <ip> --app <key> --env local --label "Office" --reason "Corporate VPN"
|
|
427
|
+
securenow allowlist remove <id>
|
|
428
|
+
securenow allowlist stats
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
### Trusted IPs
|
|
432
|
+
|
|
433
|
+
Trusted IPs are the safe bypass/suppression mechanism for known infrastructure
|
|
434
|
+
and do not enable deny-by-default allowlist mode.
|
|
435
|
+
|
|
436
|
+
```bash
|
|
437
|
+
securenow trusted # list trusted IPs
|
|
438
|
+
securenow trusted list
|
|
439
|
+
securenow trusted add <ip> [--label "CloudFlare edge"]
|
|
440
|
+
securenow trusted remove <id>
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
### False Positive Management
|
|
446
|
+
|
|
447
|
+
The `fp` command manages exclusion rules that prevent known-safe traffic from triggering security alerts.
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
securenow fp # list all exclusion rules
|
|
451
|
+
securenow fp list
|
|
452
|
+
securenow fp show <id> # rule details
|
|
453
|
+
securenow fp delete <id> [--yes]
|
|
454
|
+
|
|
455
|
+
# Create exclusion rules
|
|
456
|
+
securenow fp create \
|
|
457
|
+
--conditions '[{"field":"path","operator":"starts_with","value":"/api/health"}]' \
|
|
458
|
+
--match-mode all \
|
|
459
|
+
--rule-scope any_rule \
|
|
460
|
+
--reason "Health check endpoint"
|
|
461
|
+
|
|
462
|
+
# Shorthand safe-value presets
|
|
463
|
+
securenow fp create \
|
|
464
|
+
--path /api/events \
|
|
465
|
+
--method POST \
|
|
466
|
+
--path-safe standard \
|
|
467
|
+
--ua-safe standard \
|
|
468
|
+
--headers-safe standard \
|
|
469
|
+
--query-keys page,limit \
|
|
470
|
+
--headers-keys host,content-type \
|
|
471
|
+
--reason "Event webhook"
|
|
472
|
+
|
|
473
|
+
# Edit an existing rule
|
|
474
|
+
securenow fp edit <id> [--active true|false] [--conditions '[...]']
|
|
475
|
+
|
|
476
|
+
# Test conditions against a request body
|
|
477
|
+
securenow fp test-body '{"user":"admin"}' --conditions '[{"field":"request_body","operator":"contains","value":"\"user\":\"admin\""}]'
|
|
478
|
+
securenow fp test-body @request.json --conditions '[...]'
|
|
479
|
+
|
|
480
|
+
# Dry-run conditions against the last 3 days of live traces
|
|
481
|
+
securenow fp dry-run --conditions '[{"field":"path","operator":"starts_with","value":"/api/webhook"}]'
|
|
482
|
+
|
|
483
|
+
# AI-generate exclusion conditions from a description
|
|
484
|
+
securenow fp ai-fill --description "Stripe webhook POST to /api/stripe/webhook" \
|
|
485
|
+
--context '{"method":"POST","path":"/api/stripe/webhook"}'
|
|
486
|
+
|
|
487
|
+
# Mark an IP as false positive on a specific notification
|
|
488
|
+
securenow fp mark <notification-id> <ip> \
|
|
489
|
+
[--conditions '[...]'] \
|
|
490
|
+
[--reason "Known partner IP"] \
|
|
491
|
+
[--rule-scope this_rule|specific_rules|all_existing|any_rule] \
|
|
492
|
+
[--target-rules id1,id2]
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**Condition shape:** `{"field": ..., "operator": ..., "value": ...}` (the key is `operator`, not `op`).
|
|
496
|
+
|
|
497
|
+
**Condition fields:** `path`, `method`, `user_agent`, `status_code`, `request_body`, `request_headers`.
|
|
498
|
+
|
|
499
|
+
**Operators:** `equals`, `not_equals`, `contains`, `not_contains`, `starts_with`, `ends_with`, `regex`, `in`, `not_in`, plus structural checks — `path_safe_values`, `query_safe_values`, `query_has_only_keys`, `ua_safe_values`, `headers_safe_values`, `headers_has_only_keys`, `body_safe_values`, `body_is_format`, `body_has_only_fields`, `json_has_only_keys`, `json_safe_values`, `json_valid`, `json_max_depth`, `json_schema_match`. Prefer the `*_safe_values` checks over `contains`: they only exclude a request whose value is clean.
|
|
500
|
+
|
|
501
|
+
**Match modes:** `all` (AND logic), `any` (OR logic).
|
|
502
|
+
|
|
503
|
+
**Rule scopes:** `this_rule` (single alert rule — only via `fp mark`; for a rule-only exclusion without a notification use `securenow alerts rules exclusions <rule-id> add --conditions '[...]'`), `specific_rules` (comma-separated IDs via `--target-rules`), `all_existing` (all current rules), `any_rule` (all current and future rules; the `fp create` default).
|
|
504
|
+
|
|
505
|
+
**Safe-value presets:** `standard` or `strict`. These auto-generate conditions that whitelist common safe patterns for paths, query strings, user-agents, and headers.
|
|
506
|
+
|
|
507
|
+
---
|
|
508
|
+
|
|
509
|
+
### Instances
|
|
510
|
+
|
|
511
|
+
```bash
|
|
512
|
+
securenow instances # list ClickHouse instances
|
|
513
|
+
securenow instances list
|
|
514
|
+
securenow instances test <id> # test connection
|
|
515
|
+
```
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
### Telemetry — Emit Logs and Spans From the Shell
|
|
520
|
+
|
|
521
|
+
Mirrors the SDK's `getLogger()` and tracing APIs. Useful for cron jobs, shell scripts, and CI pipelines that need to push events into SecureNow without booting the full OTel SDK.
|
|
522
|
+
|
|
523
|
+
```bash
|
|
524
|
+
# Send a structured log record to the OTLP collector
|
|
525
|
+
securenow log send "Deployment completed" --level info --attrs version=1.2.3,service=api
|
|
526
|
+
securenow log send "Backup failed" --level error --attrs host=db-01
|
|
527
|
+
|
|
528
|
+
# Emit a test span to verify the collector accepts OTLP traffic
|
|
529
|
+
securenow test-span
|
|
530
|
+
securenow test-span "ci.smoke-test" # custom span name
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
Both commands use the default SecureNow ingestion gateway plus optional advanced `config.otel.*` overrides from `.securenow/runtime.json` or legacy runtime credentials, and return non-zero on HTTP errors so CI/cron can detect failures.
|
|
534
|
+
|
|
541
535
|
### Utilities — Redaction, CIDR, Diagnostics
|
|
542
536
|
|
|
543
|
-
The `redact` command also hides OTP credentials named `code`, `oneTimeCode`, `verificationCode`, and `passcode` (case/separator variants included), while preserving `status_code` and `error_code`. SDK capture uses the same defaults.
|
|
544
|
-
|
|
545
|
-
These mirror the SDK exports (`redactSensitiveData`, `createMatcher`, `parseCidr`) so agents can validate behavior without writing Node.
|
|
546
|
-
|
|
547
|
-
```bash
|
|
548
|
-
# Redact sensitive fields (password, token, card, ssn, etc.)
|
|
549
|
-
securenow redact '{"user":"alice","password":"s3cret","card":"4242"}'
|
|
550
|
-
securenow redact @request.json --fields internal_id,sessionHash
|
|
551
|
-
|
|
552
|
-
# CIDR operations — match an IP against a list, or parse a range
|
|
553
|
-
securenow cidr match 10.0.0.5 10.0.0.0/24,192.168.0.0/16
|
|
554
|
-
securenow cidr parse 10.0.0.0/24 # network, broadcast, mask, size
|
|
555
|
-
|
|
556
|
-
# Show resolved config (service name, endpoints, credentials, firewall layers)
|
|
557
|
-
securenow env # human-readable
|
|
558
|
-
securenow env --json # pipe to jq
|
|
559
|
-
|
|
560
|
-
# End-to-end diagnostic: probe OTLP + API endpoints, check config
|
|
561
|
-
securenow doctor # exits 0 if healthy, 1 otherwise
|
|
562
|
-
securenow doctor --json
|
|
563
|
-
```
|
|
564
|
-
|
|
565
|
-
The `redact` command accepts a JSON string or `@path/to/file.json` and layers your `--fields` flag on top of `DEFAULT_SENSITIVE_FIELDS`. Exit code from `cidr match` is `0` if the IP matches the list, `2` otherwise — scriptable.
|
|
566
|
-
|
|
567
|
-
---
|
|
568
|
-
|
|
569
|
-
## Workflow Examples for Agentic AI
|
|
570
|
-
|
|
571
|
-
### Investigate a Security Alert
|
|
572
|
-
|
|
573
|
-
```bash
|
|
574
|
-
securenow notifications list --limit 5 --json
|
|
575
|
-
# IMPORTANT: parse the ipInvestigations array for each notification — see statuses below
|
|
576
|
-
securenow ip <attacker-ip> --json
|
|
577
|
-
securenow ip traces <attacker-ip> --json
|
|
578
|
-
securenow traces show <trace-id> --json
|
|
579
|
-
securenow traces analyze <trace-id> --json
|
|
580
|
-
# Decision: block the IP
|
|
581
|
-
securenow blocklist add <attacker-ip> --reason "Automated: SQL injection detected"
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
#### Notification IP Investigation Statuses
|
|
585
|
-
|
|
586
|
-
Each notification contains an `ipInvestigations` array. **Every IP has its own `status` field** that you MUST check before taking action or raising flags. Do not rely only on top-level notification fields — always cross-reference each IP's individual investigation status.
|
|
587
|
-
|
|
588
|
-
| Status | Meaning | Action |
|
|
589
|
-
|--------|---------|--------|
|
|
590
|
-
| `open` | Still needs review — no determination yet | Investigate: run `securenow ip <ip>`, check traces, decide to block or dismiss |
|
|
591
|
-
| `false_positive` | Trusted/dismissed by exclusion rule, verified bot, or trusted IP list | **Skip** — greyed out in UI, no action needed |
|
|
592
|
-
| `blocked` | Already on the user's blocklist | **Skip** — already handled |
|
|
593
|
-
| `clean` | Pipeline analyzed and cleared as benign | **Skip** — verified safe |
|
|
594
|
-
|
|
595
|
-
**Critical workflow rule:** When investigating notifications, iterate `ipInvestigations[]` and **only flag or act on IPs with `status: "open"`**. IPs marked `false_positive`, `blocked`, or `clean` have already been triaged — do not re-flag them.
|
|
596
|
-
|
|
597
|
-
### Triage and Suppress a False Positive
|
|
598
|
-
|
|
599
|
-
```bash
|
|
600
|
-
securenow notifications list --json
|
|
601
|
-
# Identify a false positive notification
|
|
602
|
-
securenow fp ai-fill --description "Stripe webhook calls to /api/stripe/webhook"
|
|
603
|
-
# Review the suggested conditions, then create the rule
|
|
604
|
-
securenow fp create --conditions '<ai-suggested-conditions>' --rule-scope any_rule --reason "Stripe webhook"
|
|
605
|
-
# Or directly mark the notification's IP as FP
|
|
606
|
-
securenow fp mark <notification-id> <ip> --rule-scope this_rule --reason "Known Stripe IP"
|
|
607
|
-
```
|
|
608
|
-
|
|
609
|
-
### Onboard a New Application
|
|
610
|
-
|
|
611
|
-
```bash
|
|
612
|
-
securenow apps create my-new-app --hosts api.example.com,app.example.com
|
|
613
|
-
securenow apps default my-new-app
|
|
614
|
-
securenow login
|
|
615
|
-
securenow init
|
|
616
|
-
securenow run src/index.js
|
|
617
|
-
securenow status --json
|
|
618
|
-
```
|
|
619
|
-
|
|
620
|
-
### Security Posture Check
|
|
621
|
-
|
|
622
|
-
```bash
|
|
623
|
-
securenow status --json
|
|
624
|
-
securenow firewall status --json
|
|
625
|
-
securenow blocklist stats --json
|
|
626
|
-
securenow
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
securenow apps
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
|
648
|
-
|
|
649
|
-
| `
|
|
650
|
-
| `
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
| `Unknown command` | Typo or unrecognized command | `securenow help` |
|
|
654
|
-
|
|
655
|
-
SecureNow-specific environment overrides are intentionally unsupported for troubleshooting; use explicit CLI config files and normal terminal logs.
|
|
537
|
+
The `redact` command also hides OTP credentials named `code`, `oneTimeCode`, `verificationCode`, and `passcode` (case/separator variants included), while preserving `status_code` and `error_code`. SDK capture uses the same defaults.
|
|
538
|
+
|
|
539
|
+
These mirror the SDK exports (`redactSensitiveData`, `createMatcher`, `parseCidr`) so agents can validate behavior without writing Node.
|
|
540
|
+
|
|
541
|
+
```bash
|
|
542
|
+
# Redact sensitive fields (password, token, card, ssn, etc.)
|
|
543
|
+
securenow redact '{"user":"alice","password":"s3cret","card":"4242"}'
|
|
544
|
+
securenow redact @request.json --fields internal_id,sessionHash
|
|
545
|
+
|
|
546
|
+
# CIDR operations — match an IP against a list, or parse a range
|
|
547
|
+
securenow cidr match 10.0.0.5 10.0.0.0/24,192.168.0.0/16
|
|
548
|
+
securenow cidr parse 10.0.0.0/24 # network, broadcast, mask, size
|
|
549
|
+
|
|
550
|
+
# Show resolved config (service name, endpoints, credentials, firewall layers)
|
|
551
|
+
securenow env # human-readable
|
|
552
|
+
securenow env --json # pipe to jq
|
|
553
|
+
|
|
554
|
+
# End-to-end diagnostic: probe OTLP + API endpoints, check config
|
|
555
|
+
securenow doctor # exits 0 if healthy, 1 otherwise
|
|
556
|
+
securenow doctor --json
|
|
557
|
+
```
|
|
558
|
+
|
|
559
|
+
The `redact` command accepts a JSON string or `@path/to/file.json` and layers your `--fields` flag on top of `DEFAULT_SENSITIVE_FIELDS`. Exit code from `cidr match` is `0` if the IP matches the list, `2` otherwise — scriptable.
|
|
560
|
+
|
|
561
|
+
---
|
|
562
|
+
|
|
563
|
+
## Workflow Examples for Agentic AI
|
|
564
|
+
|
|
565
|
+
### Investigate a Security Alert
|
|
566
|
+
|
|
567
|
+
```bash
|
|
568
|
+
securenow notifications list --limit 5 --json
|
|
569
|
+
# IMPORTANT: parse the ipInvestigations array for each notification — see statuses below
|
|
570
|
+
securenow ip <attacker-ip> --json
|
|
571
|
+
securenow ip traces <attacker-ip> --json
|
|
572
|
+
securenow traces show <trace-id> --json
|
|
573
|
+
securenow traces analyze <trace-id> --json
|
|
574
|
+
# Decision: block the IP
|
|
575
|
+
securenow blocklist add <attacker-ip> --reason "Automated: SQL injection detected"
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
#### Notification IP Investigation Statuses
|
|
579
|
+
|
|
580
|
+
Each notification contains an `ipInvestigations` array. **Every IP has its own `status` field** that you MUST check before taking action or raising flags. Do not rely only on top-level notification fields — always cross-reference each IP's individual investigation status.
|
|
581
|
+
|
|
582
|
+
| Status | Meaning | Action |
|
|
583
|
+
|--------|---------|--------|
|
|
584
|
+
| `open` | Still needs review — no determination yet | Investigate: run `securenow ip <ip>`, check traces, decide to block or dismiss |
|
|
585
|
+
| `false_positive` | Trusted/dismissed by exclusion rule, verified bot, or trusted IP list | **Skip** — greyed out in UI, no action needed |
|
|
586
|
+
| `blocked` | Already on the user's blocklist | **Skip** — already handled |
|
|
587
|
+
| `clean` | Pipeline analyzed and cleared as benign | **Skip** — verified safe |
|
|
588
|
+
|
|
589
|
+
**Critical workflow rule:** When investigating notifications, iterate `ipInvestigations[]` and **only flag or act on IPs with `status: "open"`**. IPs marked `false_positive`, `blocked`, or `clean` have already been triaged — do not re-flag them.
|
|
590
|
+
|
|
591
|
+
### Triage and Suppress a False Positive
|
|
592
|
+
|
|
593
|
+
```bash
|
|
594
|
+
securenow notifications list --json
|
|
595
|
+
# Identify a false positive notification
|
|
596
|
+
securenow fp ai-fill --description "Stripe webhook calls to /api/stripe/webhook"
|
|
597
|
+
# Review the suggested conditions, then create the rule
|
|
598
|
+
securenow fp create --conditions '<ai-suggested-conditions>' --rule-scope any_rule --reason "Stripe webhook"
|
|
599
|
+
# Or directly mark the notification's IP as FP
|
|
600
|
+
securenow fp mark <notification-id> <ip> --rule-scope this_rule --reason "Known Stripe IP"
|
|
601
|
+
```
|
|
602
|
+
|
|
603
|
+
### Onboard a New Application
|
|
604
|
+
|
|
605
|
+
```bash
|
|
606
|
+
securenow apps create my-new-app --hosts api.example.com,app.example.com
|
|
607
|
+
securenow apps default my-new-app
|
|
608
|
+
securenow login
|
|
609
|
+
securenow init
|
|
610
|
+
securenow run src/index.js
|
|
611
|
+
securenow status --json
|
|
612
|
+
```
|
|
613
|
+
|
|
614
|
+
### Security Posture Check
|
|
615
|
+
|
|
616
|
+
```bash
|
|
617
|
+
securenow status --json
|
|
618
|
+
securenow firewall status --json
|
|
619
|
+
securenow blocklist stats --json
|
|
620
|
+
securenow forensics "summarize all attacks in the last 7 days"
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### Discover Attack Surface
|
|
624
|
+
|
|
625
|
+
```bash
|
|
626
|
+
securenow apps discover --domain example.com
|
|
627
|
+
securenow apps scan --yes
|
|
628
|
+
```
|
|
629
|
+
|
|
630
|
+
---
|
|
631
|
+
|
|
632
|
+
## Output Parsing
|
|
633
|
+
|
|
634
|
+
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.
|
|
635
|
+
|
|
636
|
+
## Error Handling
|
|
637
|
+
|
|
638
|
+
| Exit code / Error | Meaning | Recovery |
|
|
639
|
+
|------------------|---------|----------|
|
|
640
|
+
| `Session expired` | Admin JWT expired | `securenow admin login` (or `admin login --global` for shared admin auth) |
|
|
641
|
+
| `Not logged in` | No admin token found | `securenow admin login`; runtime `.securenow/runtime.json` is unrelated |
|
|
642
|
+
| `Access denied (403)` | Insufficient plan or permissions | Upgrade plan or check user role |
|
|
643
|
+
| `Cannot connect` | API unreachable | Check `securenow config get apiUrl` or network |
|
|
644
|
+
| `Unknown command` | Typo or unrecognized command | `securenow help` |
|
|
645
|
+
|
|
646
|
+
SecureNow-specific environment overrides are intentionally unsupported for troubleshooting; use explicit CLI config files and normal terminal logs.
|