Browse resources

Run your instance

Security and privacy

Accounts, keys and tokens, and exactly what data is collected.

knotel runs in your Cloudflare account and stores everything in your own R2 bucket and D1 database. Nothing is sent to a third party.

Accounts

  • There is no public sign-up. The first account claims the instance with the setup code; after that, only signed-in members can add accounts.
  • Every member can see all projects and manage settings. There are no roles yet.
  • Passwords are at least 8 characters. Sessions last 30 days and renew while in use.
  • Removing a member signs them out immediately and revokes their access tokens.

Keys and tokens

  • Ingest keys and access tokens are random secrets shown once. Only their SHA-256 hash is stored.
  • Ingest keys can only write spans to one project. They can't read anything, which is why they're safe in a web page.
  • Every ingest key lists where it accepts data from, on the project's Send data page: domains (example.com, *.example.com), matched against the Origin header a browser sends, and IP addresses or CIDR ranges (203.0.113.7, 2001:db8::/64), matched against the address the request came from. Anything else gets a 403 before the body is read, and is counted as blocked on the Usage page. A key can't be saved with an empty list. Changes reach ingest within a minute.
  • To accept data from anywhere — a sender whose address you don't know yet, or a first look at an instance — list 0.0.0.0/0 and ::/0. Both: a range only matches its own address family, so the IPv4 entry alone turns away every IPv6 sender. * is refused on purpose, so that accepting everything is something you wrote down rather than a default. A key with those two on it works for whoever copies it, so treat it as public.
  • A domain stops another site from reusing a key copied out of your page, because a browser won't let a page lie about its origin. It doesn't stop a script, which can send any Origin it likes. An IP address can't be forged, so give servers their own key with only IPs on it and keep the domain-restricted key for the browser. If junk still arrives, revoke the key and create another.
  • A Cloudflare Worker has no address of its own: requests from one arrive from a shared Cloudflare address. List the zone the Worker runs on instead (example.com); it's matched against the CF-Worker header Cloudflare adds to a Worker's requests.
  • Keys created before allowed sources existed accept data from anywhere until you give them a list. The Send data page marks them.
  • Access tokens read every project as their owner. Keep them out of repositories and client-side code.
  • The R2 SQL API token is powerful: it can read and write the R2 bucket holding your spans. Keep it in Secrets Store, never in the repository, and rotate it if it leaks.
  • Revoking deletes the cached lookup at once, but a Worker instance that saw the credential in the last minute may accept it for up to a minute more.

What gets collected

The browser script sends:

  • URLs without query strings, and the page referrer
  • Timings of page loads and fetches, and response status codes
  • Error messages and stack traces
  • The user agent and a random per-tab session id

It doesn't read cookies, storage, form fields, or request and response bodies, and knotel doesn't store client IP addresses. The Worker SDK records method, URL (without query string), status, user agent and Cloudflare colo.

Keep secrets and personal data out of spans
Custom attributes, span names, database query text and error messages are stored as sent, and history in R2 is not deleted automatically. Don't put passwords, tokens or personal data in them, and prefer parameterised query text.