Knsept
docs Risk Scanner

Scanner docs.

How to run it, what each rule checks, and what it can't see.

Run it

Try it on sample data first:

npx knsept scan --demo

Create a read-only API token in your Cloudflare dashboard with Account Analytics Read,Workers Read, Queues Read and D1 Read, then:

CLOUDFLARE_API_TOKEN=… npx knsept scan
  • --account <id>: which account to scan, or set CLOUDFLARE_ACCOUNT_ID
  • --days <n>: whole UTC days of usage to read, 1 to 31 (default 3)
  • --json: print the report as JSON

The projection

Usage in the window is scaled to a 30-day month, included usage comes off, and Cloudflare's list prices apply. It's an estimate of a month like the one scanned, not an invoice.

What it can't see

Every report ends with a list of what couldn't be measured for your account. A rule that sees nothing can't tell "none" from "unknown", so read that list too.

Brakes

With Guard Solo, a queue that goes over its own daily budget can be paused automatically. Delivery stops until you resume it: messages wait in the queue for its retention period (4 days by default), and producers can still send, which is billed. The pause happens in your account, through a small Worker you deploy: theBrake Worker. It holds a token that can edit your queues; Guard never does.

  1. Create an API token with only Queues Edit on your account, and deploy the Brake Worker with that token, your account ID and the names of the queues it may pause. Its README has the commands.
  2. In the Guard dashboard, under Brakes, paste the Worker's workers.dev address. Guard shows you a signing secret, once: set it as the Worker's BRAKE_SECRET.
  3. Press Test the Brake Worker. It lists the queues it can pause.
  4. Give a queue its own budget and tick Pause this queue's delivery when it goes over.

When that queue passes its budget, Guard asks the Brake Worker to pause it and emails you. Resume it from the dashboard, or in Cloudflare. A queue you resume isn't paused again until the next UTC day. A paused queue doesn't resume by itself the next day. The Brake Worker only acts on a request signed with your secret, less than two minutes old and never seen before, for a queue on its list.

rules What each rule checks

Five rules.

A high cost alone is never a finding. It only raises the severity of a real signal.

queue-retry-storm

A queue's messages are retried 0.25 times or more each on average, or a consumer allows over 10 retries with no dead letter queue.

Fix: Ack messages one by one, set retry_delay, keep max_retries low and add a dead_letter_queue.

cron-cost-growth

CPU per run doubled across the window, one run uses half of the 15-minute CPU limit, or a cron runs every 5 minutes or more often with over a second of CPU.

Fix: Process a bounded batch per run with a saved cursor.

d1-full-scan

A statement reads at least 1,000 rows per run, and at least 100 rows for every row it returns or writes.

Fix: Add an index on the columns in its WHERE clause, then check EXPLAIN QUERY PLAN.

d1-no-external-copy

A database holds data. The scanner can't see copies kept elsewhere, so it lists every database as a reminder.

Fix: Export on a schedule to storage you control, and test a restore.

do-alarm-loop

Alarms fire at 1 a second or more, or one object re-arms more often than every 10 seconds. Cloudflare's analytics don't report alarms separately, so this rule can't fire on real accounts yet.

Fix: Only call setAlarm() when there is more work, with a minimum delay.