Security
Security and privacy: fail open, every time
A camada outage or a camada bug must never return a 5xx from your app. That rule shapes every part of the SDK.
- camada is unreachable
- The SDK keeps serving with the snapshot it already has. Events that cannot ship are dropped, never retried on your request path.
- The SDK throws
- Errors inside the SDK are caught and logged. Your handler runs as if camada were not installed.
- Cold serverless instance
- No snapshot is loaded yet, so the first request passes. The snapshot loads asynchronously and enforcement starts on the next request.
- You want it off now
- Set CAMADA_DISABLED=1. It is checked per request; no redeploy needed if your platform reloads env.
- A rule needs a signal your position lacks
- ASN, country and TLS fingerprint cannot be evaluated inside a Node or Next app, so blocks keyed on them are skipped there. TLS fingerprint entries are enforced in your app only on Cloudflare Workers, by @camada/hono and by @camada/sveltekit with adapter-cloudflare. Path entries enforce in every SDK. IP entries enforce once the client IP resolves.
Data
What leaves your app
One event per request. This is the whole list.
| Request line | method, host, path and query string; query values that look like tokens, keys or passwords are replaced before shipping |
|---|---|
| Response | status code and latency (Node SDK), content type and length |
| Headers | names, sizes and order; User-Agent, Accept, Accept-Language, client hints, Sec-Fetch-*, Referer and Origin; the Authorization scheme name only |
| Network | client IP resolved through your trusted-proxy setting, plus ASN, country and TLS fingerprint where the position exposes them |
| Session | the first-party _sfp cookie value and a per-request id |
| Beacon | screen and window size, timezone, languages, platform, WebGL renderer, canvas hash, automation flags, input event counts, timing |
| App outcomes | the event name you pass to track() and an HMAC of the identifier, computed in your process |
What never leaves your app
- Authorization and Cookie header values
- Request and response bodies (field names and sizes only)
- Query values matching token, key or password patterns
- Raw user ids, emails or anything you pass to track() before hashing
Redaction runs inside the SDK against a fixed allowlist. You can add fields to capture; there is no option to capture less carefully. The SDKs are open source so the allowlist can be audited. The Worker adds a second guard: it accepts an Authorization scheme name only, and a user id only when it is hash-shaped.
Trust boundary
Client IP and proxies
ASN and country rules apply where the collecting position exposes them. A Cloudflare Worker running @camada/hono, or @camada/sveltekit with adapter-cloudflare, sees both, and a TLS fingerprint besides; the Node and Next.js SDKs see neither, so those rules stay off inside your app. Next.js on Vercel sends the JA4 TLS digest in its events, where it is used for scoring, not for enforcement, so a fingerprint entry never blocks a request in a Next.js or Node app. Which key types your own project can enforce is reported per project in the app; what each one is for is on the rules page.
The SDK never trusts a raw X-Forwarded-For. It resolves the client IP from your project's trusted-proxy setting (a hop count, a CIDR list, or the Vercel preset). Without one, the socket peer is used in Node. Next.js middleware has no socket peer, so off Vercel it needs the CAMADA_TRUSTED_PROXY setting (or one set in the app) before IP entries enforce there; on Vercel it defaults to the Vercel preset. A spoofed header can never put an address on your blocklist.
Retention
How long data is kept
- Raw events: 7 days on every plan, then deleted.
- Verdicts, blocks, greylist rows and run reports: 7, 30, 90 or 365 days by plan.
- Audit log entries: at least one year.
- Deleting a project removes all of its data within 30 days. You can request an export of a project's data as JSON.
IP addresses are personal data. The privacy policy and DPA state the purposes: detecting and blocking abusive traffic against your project, and reputation as described below.
Disclosure
Cross-tenant reputation
An IP address that gets a malicious verdict is remembered for seven days. Once three or more other paying organizations have flagged it, it scores higher at your projects. Trial projects, projects still in their learning period and other projects in your own organization do not count, and an address you allowed, cleared or ignored is not raised. Only IP addresses are scored this way. For a TLS fingerprint, the investigation agent can read the same kind of record as context, but it does not change the score. The reputation store holds the key, the verdict and counts. It never holds which tenant saw it, and no project can see another project's traffic. camada never shows you who flagged an address.
Where
Data location and sub-processors
camada runs on Cloudflare's global network; storage is Cloudflare R2, D1 and KV. EU-only residency is not offered yet. The full list of sub-processors, with what each one does, is on the sub-processors page.
Chat
Where the agent runs
The in-app agent runs on Cloudflare Workers AI (glm-5.3-flash) through Cloudflare AI Gateway: your question, the tool results it read to answer it and the conversation so far never leave Cloudflare, and no third-party model provider is involved. It is available on the plans that include chat; when the primary model or the gateway is unavailable a second Workers AI model answers instead. The agent is scoped to one project by your session, never by the model, and traffic text reaches the model as delimited data rather than as instructions. The whole picture is on the chat page, and every provider is listed on the sub-processors page.
Access
How camada staff can reach your organization
camada staff are not members of your organization. They sign in with a separate camada staff account, and having one grants no access to your data by itself.
- To open your organization at all, a staff member has to start an impersonation session and write down a reason. There is no other way in.
- The session is time-boxed: it ends by itself after 60 minutes, and can be stopped sooner.
- While it runs, that person acts as an administrator of your organization and of no other.
- Your audit log records the start and the end of the session with the reason, and every change made during it carries the staff member's identity and that reason — never one of your own accounts.
- Anyone in your organization who can read the audit log can read all of that afterwards, without asking us.
Platform
The app and this site
- Sign-in runs inside camada on Cloudflare with Better Auth, which is open source, by email code or Google; the app holds a signed session cookie and keeps only display preferences in browser storage.
- Every app route checks the session and your membership in the organization. Ids that belong to another organization return 404.
- Every change in the app writes an audit row: who, what, before, after.
- The app and this site ship a content security policy, HSTS and
frame-ancestors 'none'. - This site sets no cookies and uses cookieless analytics when enabled.
Found a vulnerability? Write to security@camada.app. We acknowledge every report.