Create Custom Alert Rules From the Command Line
SecureNow 8.1 adds `securenow alerts rules create` — define your own detection rules from SQL, scope them to your apps, and ship them without leaving the terminal. Here's how, with a real magic-link brute-force example.
Create Custom Alert Rules From the Command Line
SecureNow ships with a large library of built-in detection rules — brute force, credential stuffing, scanner fingerprints, injection signatures. But every app has a threat model the defaults don't quite cover: a login flow with its own quirks, a checkout endpoint worth watching, an internal API that should never see traffic from outside one ASN.
Until now, turning that knowledge into a detection rule meant opening the dashboard. As of SecureNow 8.1, you can do it from the terminal:
npm install -g securenow@latest
securenow alerts rules create \
--name "Auth: magic-link brute force" \
--sql @rule.sql \
--apps <app-key> \
--severity high \
--nlp "single IP flooding /api/auth/signin or /api/auth/callback"
Detection-as-code, versioned in your repo, shippable from CI. No clicking.
Why this matters
Detection rules are configuration, and configuration belongs in version control. When a rule lives only in a dashboard, you lose the things you take for granted everywhere else in your stack: code review on the query, a diff when someone changes a threshold, the ability to recreate your whole security posture in a fresh environment with one script.
securenow alerts rules create closes that gap. The rule's SQL is a file in your repo. Creating the rule is a command in your deploy pipeline. Tuning it later is a reviewed change.
How it works
A SecureNow detection rule is just a SQL query that runs on a schedule against your trace telemetry in ClickHouse. The query returns the offending IPs; SecureNow aggregates them, raises a notification, and — if you have automation or rate-limit rules wired up — remediates.
Two conventions make the SQL portable:
__USER_APP_KEYS__— a placeholder SecureNow replaces with the rule's scoped application keys at runtime. Always filter on it so the rule only ever sees your own traffic.- an
ipcolumn — select the client IP so SecureNow can group matches per IP and hand them to remediation.
That's the whole contract. Everything else is ordinary SQL.
A real example: magic-link login abuse
Passwordless (magic-link) login has a specific abuse surface: a single IP hammering the request endpoint to flood a victim's inbox, or hammering the callback endpoint to brute-force verification tokens. Here's a rule that flags any IP making 20+ requests to the auth endpoints in 15 minutes.
Save the query as rule.sql:
SELECT
coalesce(
nullIf(attributes_string['http.client_ip'], ''),
nullIf(attributes_string['net.peer.ip'], ''),
nullIf(attributes_string['network.peer.address'], ''),
nullIf(attributes_string['client.address'], '')
) AS ip,
count() AS request_count,
countDistinct(attributes_string['http.target']) AS distinct_targets
FROM signoz_traces.distributed_signoz_index_v3
WHERE resource_string_service$$name IN (__USER_APP_KEYS__)
AND timestamp >= now() - INTERVAL 15 MINUTE
AND (
attributes_string['http.target'] LIKE '/api/auth/signin%'
OR attributes_string['http.target'] LIKE '/api/auth/callback%'
)
GROUP BY ip
HAVING ip != '' AND request_count >= 20
ORDER BY request_count DESC
LIMIT 100
Then create the rule:
securenow alerts rules create \
--name "Email login abuse - magic-link flood & token brute-force (single IP)" \
--description "Single IP making excessive magic-link signin or token-callback requests" \
--nlp "Detect a single IP sending too many /api/auth/signin or /api/auth/callback requests in 15 minutes" \
--category auth \
--severity high \
--apps <your-app-key> \
--sql @rule.sql
SecureNow validates the SQL, stores the query, creates the rule on a 15-minute schedule, and routes matches to your in-app channel. Confirm it runs cleanly before trusting it:
securenow alerts rules test <rule-id> --app <your-app-key> --mode dry_run --wait
A complete status with no error means the query is valid against your live data — even if it returns zero rows today, which is exactly what you want from a preventive rule.
The flags
| Flag | Purpose |
|---|---|
--name | Rule name (required) |
--sql <sql|@file|-> | Detection SQL — inline, from a file with @, or - for stdin |
--apps k1,k2 / --applications-all | Scope to specific apps, or all current & future apps |
--severity | critical, high, medium, or low |
--schedule | Cron expression (default */15 * * * *) |
--nlp | Plain-English intent stored with the query |
--throttle-minutes N / --no-throttle | Notification throttle window |
--execution-mode | scheduled, instant, or hybrid |
--channel id1,id2 | Override the alert channel (defaults to your in-app SecureNow channel) |
--query-mapping-id | Reuse a saved query instead of --sql |
Reusing an existing saved query? Pass --query-mapping-id instead of --sql. Want to keep the rule and its query side by side with the rest of your infrastructure? Commit rule.sql and the create command into your deploy scripts.
From detection to response
A detection rule is one half of the loop. Pair it with SecureNow's remediation primitives, all of which are also scriptable from the CLI:
# Soft: rate-limit the abused route inline at the firewall
securenow ratelimit add --app <key> --route /api/auth/signin \
--mode prefix --method POST --limit 10 --window 15m
# Hard: auto-block IPs your detection flags as high risk
securenow automation create --name "Block high-risk auth abusers" \
--conditions '[{"field":"riskScore","operator":"gte","value":90}]' \
--actions '[{"type":"addToBlocklist","config":{"ttlHours":72,"method":"ALL"}}]'
Detection in SQL, response in policy, both in version control. That's the workflow securenow alerts rules create was built for.
Get it
npm install -g securenow@latest # 8.1.0 or newer
securenow login # authenticate the CLI
securenow alerts rules create --help
Full reference lives in the bundled CLI skill (securenow help alerts rules) and the SecureNow docs. If you describe your threat model in --nlp and keep the SQL in your repo, your detection logic stays as reviewable as the rest of your code.
Frequently Asked Questions
Do I still need the dashboard to create detection rules?
No. As of SecureNow 8.1 you can create a full custom detection rule with `securenow alerts rules create` straight from the terminal or CI. The dashboard remains available for browsing, tuning, and reviewing — but rule creation is now scriptable.
What does the detection SQL run against?
Your trace telemetry in ClickHouse. Scope the query to your apps with the `__USER_APP_KEYS__` placeholder and select an `ip` column so SecureNow can aggregate matches per IP and hand them to remediation (block, rate-limit, or notify).
What permissions does it need?
An API key with the `alerts:write` scope, or an authenticated admin CLI session via `securenow login`.
Recommended reading
A copy-paste prompt that lets an AI coding agent install SecureNow, wire Next.js instrumentation, verify traces and logs, deploy to AWS, simulate attacks, and prove firewall blocking with human approval gates.
May 18
If your team uses Sentry for frontend errors and needs backend distributed tracing without doubling the Sentry bill, here's the OpenTelemetry path that doesn't make you choose.
May 9Five approaches to bot blocking in Express, ranked by effort vs. effectiveness. From a 5-line allowlist to a full IP-reputation firewall — all without Cloudflare, AWS WAF, or any new infrastructure.
May 9