Skip to content
camada
Menu

How it works

How camada works: events in, analysis, blocklist out

Your app runs one camada package. It collects events and enforces the blocklist. The analysis runs in a Cloudflare Worker that stores, scores and investigates, with Watchkeeper, camada's AI analyst, writing the verdicts. Nothing on your request path waits for camada.

  1. 1 · Your app

    SDK

    One redacted event per request, batched, off the request path.

  2. 2 · camada

    Ingest

    Raw events land in R2 per tenant and hour. Beacon rows join by request id.

  3. 3 · camada

    Score

    Every 10 minutes by default: features per IP, session and TLS fingerprint, scored against 63 rules.

  4. 4 · camada

    Investigate

    A triage model sorts the grey ones. An investigation agent takes the worst and writes a verdict with evidence.

  5. 5 · camada

    Snapshot

    Verdicts become a per-tenant blocklist. The SDK pulls it every 30 s; unchanged costs a 304.

Then back to step 1: the SDK enforces the snapshot in your process and answers matches with a 403 before your handler runs.

Step 1

Events in

After each response finishes, the SDK builds one event: method, path, query shape, status, latency, header names and sizes, client IP resolved through your trusted-proxy config, the session id, and a request id. It redacts before anything leaves the process, batches events, and posts them without blocking the response.

The SDK also serves the browser beacon from your own origin at /_cam/b.js. No third-party domain, so ad blockers and your CSP do not break it. The beacon posts screen, timezone, languages, renderer, automation flags and input counts to /_cam/fp, and the request id joins it to the server event.

Every event carries a tap (where it was collected) and the Worker stamps a capability mask. A Node SDK sees true header order and app outcomes but not TLS. A Next.js middleware on Vercel sees a JA4 digest but not the final status. Rules only fire where the tap could have seen the signal, so an absent signal is never counted against you.

Step 2

Analysis

Each project with new events gets one run every 10 minutes by default. The minimum interval is 5 minutes. The run reads the window, builds features per IP, per session and per TLS fingerprint, and scores each one against 63 rules. Six of them subtract points for signs of a real person. At the default sensitivity, thirty points is grey and sixty sends the client to investigation.

Grey clients go to a triage model fifteen at a time. Clients at sixty, or triaged as suspicious or malicious, go to an investigation agent, up to 10 per run, highest scores first. The agent can pull raw request samples and the facts you recorded about your site, and its prompt already carries the client's reputation and network (ASN) context. It gets at most 3 tool rounds, then writes a verdict with the evidence it used. Verdicts younger than six hours are not re-investigated.

Each run ends with a markdown report you can read in the app.

Signals

SignalSourceWhat it tells
Client IP, ASN, countryrequest headers, edge metadatahosting ASN on a login route; geo velocity across a session
TLS fingerprintedge metadata, Vercel JA4 digestone fingerprint across many IPs and user agents is a tool or a botnet
Header names, sizes, orderthe request as your server sees itbrowsers send 15 to 25 headers in a stable order; libraries do not
Client hints, Sec-Fetch, Acceptrequest headersa Chrome user agent without Sec-CH-UA is headless, a proxy or a lie
Path, query shape, methodrequest linescanner paths like /.env or /wp-login.php; parameter stuffing
Status, latencyresponse finish (Node SDK)404 ratio over 50%; logins failing in bursts
Session cookiefirst-party _sfpa new session on every request is a client that drops cookies
Browser beaconfirst-party /_cam/b.jswebdriver flag, software WebGL renderer, zero input events across a session
App outcomesyour track() callslogin failed, signup, checkout declined: ground truth no edge position sees

Rule weights: a sample of the 63

RuleWeight
webdriver true or automation globals present+60
beacon user agent differs from header user agent+40
hosting or cloud ASN on a login route+30
one TLS fingerprint seen from 50+ IPs within one run window+30
3+ HTML pages served and no beacon (no JavaScript ran)+25
404 ratio over 50% with 20+ requests+25
web shell or exploit-kit path (shell.php, /vendor/phpunit, /boaform)+60
secret or config file probe (/.env, /.git, wp-config.php, *.sql)+30 per distinct path, cap 60
scanner path hit (/wp-login.php, /xmlrpc.php, /phpinfo.php)+20 per distinct path, cap 60
claims Googlebot or bingbot from outside the published IP ranges+60
password spray: failed logins on 10+ of your accounts, 2 tries each (track())+50
flagged malicious by 3+ other paying organizations in the last 7 days+40
beacon with input events within 10 seconds-30
consistent user agent, client hints, TLS family and beacon engine-15

Rules that need ASN or country read them from the request where the position exposes them (edge taps, Hono on Workers) and from the analyst's own geo tables otherwise, so they score every tap; enforcing an ASN or country entry per request still needs a position that sees them. The in-app SDKs (Node, Next.js, Python, Go, PHP, Ruby, Java and .NET) fail open on those entries. Negative weights let humans fall out of grey. You can disable any rule, change what a category does (block, challenge, alert, ignore) and pick a sensitivity per project. Once enforcement is on, a challenge verdict makes your SDK answer with a small proof-of-work page that a real browser solves. SDK versions older than snapshot v4, and any SDK set to challenge: false, treat it as a recommendation. How a challenge works.

Step 3

Blocklist out

A verdict becomes a block row with a TTL. When the set of active blocks changes, the Worker publishes a new per-tenant snapshot. The SDK polls it every 30 seconds with an ETag, so an unchanged snapshot costs a 304 and nothing else.

Enforcement happens in your process before your handler runs: a matching IP or path gets a 403 with x-block-reason. The blocked request still ships as an event, so you can see what was stopped.

A new project starts in a learning window. During it, verdicts are recommendations you can review in the app. camada never switches a project to enforce on its own. You end the review and turn it on.

Next

Read the limits before you install

Fail-open behaviour, cold starts, what each position can and cannot enforce, and what data leaves your app are on the security page. Install steps per framework are under frameworks. What this looks like for one attack at a time: credential stuffing, scraping, AI agent abuse, CVE exploit scans.