Security

How ClickClacks protects your data

How ClickClacks protects your account, your organization and the people you measure. Everything on this page describes how the product works today.

01 · Infrastructure

Runs on Cloudflare, with a ClickHouse reporting database.

The application, its database, event collection and email run on Cloudflare. Reports are read from a ClickHouse database we host on DigitalOcean, reachable only through a private Cloudflare tunnel.

Hosting

Cloudflare

Application
Cloudflare Workersapp.clickclacks.io
Accounts and settings
Cloudflare D1SQL database
Events and heatmaps
Pipelines, R2, Durable ObjectsCloudflare storage
Reporting database
ClickHouseDigitalOcean
Email
Cloudflare Emailfrom clickclacks.io
Bot protection
Cloudflare Turnstileon sign-in

02 · Your account

Sign-in, passwords and sessions.

Sign-in

Four ways to sign in

Sign in with a passkey, a one-time link or code sent to your email, or an email and password. Google and GitHub sign-in are switched off. Email links expire after 10 minutes and codes after 5, and each works once.

Passwords

Hashed with scrypt

Passwords are 8 characters or more and are stored as a salted scrypt hash. Your email address has to be verified before a password works. A reset link lasts 15 minutes, works once and signs out every session.

Two-factor

Authenticator app and recovery codes

Turn on two-factor authentication with an authenticator app. You get single-use recovery codes, shown once. The secret and the codes are stored encrypted, and ten wrong attempts lock verification for 15 minutes.

Re-checks

Sensitive changes ask again

Turning two-factor off, removing a passkey, transferring ownership and deleting an organization each ask you to confirm it's you first. Changing your password signs out your other sessions.

Sessions

Seven-day sessions you can end

A session lasts seven days. Its cookie is HttpOnly and Secure, so scripts on the page can't read it. Your settings list every device that is signed in, and you can sign out any other device from there.

Attempts

Rate limits and a bot check

Sign-in, sign-up and password recovery are rate-limited per address. Repeated attempts have to pass a Cloudflare Turnstile challenge, and passing it doesn't lift the limit. Sign-in and reset pages don't reveal whether an email has an account.

03 · Your organization

Roles, the audit log, keys and isolation.

Roles

Owner, Admin, Member, or your own

Every organization starts with three protected roles. Owners can add custom roles with exactly the permissions a teammate needs.
  • OwnerSettings, roles, members, developer keys, audit log
  • AdminMembers and invitations, audit log
  • MemberNo administrative permissions

Audit log

An audit log that can't be edited

Invitations, membership and role changes, API keys, webhooks and server keys are recorded in an audit log that Owners and Admins can read. Secrets are redacted before an entry is saved, and the database refuses edits and deletions afterwards.

Developers

Keys are stored as hashes

The API keys, MCP keys and server keys you create are shown once and stored as a SHA-256 hash. Any of them can be revoked. Webhook deliveries go over HTTPS and are signed with HMAC-SHA-256, and each endpoint's signing secret is stored encrypted.

Isolation

One organization can't read another's data

Every request checks on the server that you belong to the organization in the address. A report query is refused unless it is limited to one project you may open. The reporting database applies the same limit with a row policy, and the app reads it through a read-only user.

Our access

Support access is limited and logged

Staff accounts must use two-factor or a passkey. To help with a problem, a staff member can act as one of your members only after giving a written reason, for 15 minutes at most. It appears in your audit log, and it can't transfer ownership.

04 · Your visitors

What the tracker leaves out.

The tracker removes the most sensitive data in the browser, before anything is sent. This is on by default.

URL scrubbing

Secrets are stripped from every URL

Before a pageview is sent, the tracker removes query parameters that look like secrets from the page address and the referrer. Add data-query="off" to drop query strings entirely.

Visited /reset?token=9f2c…&email=ana@acme.com&ref=mail
Stored/reset?ref=mail

Parameters removed, in any letter case:

  • code
  • password
  • passwd
  • pwd
  • auth
  • authorization
  • session
  • sessionid
  • sid
  • sig
  • signature
  • otp
  • apikey
  • email
  • phone
  • ssn
  • card
  • cvv
  • …_token
  • …_key
  • …_secret

Names ending in token, key or secret are caught with or without a _ or - before them.

Heatmaps

Screenshots are masked before upload

Form fields, embedded frames, video and canvas are replaced with grey blocks, and so is anything you mark data-cc-mask. Email addresses and digits in the remaining text become dots. The tracker never reads what people type into a form.

Domains

Only on your domains

The tracker only runs on the domains in its data-domains list, and we reject browser events sent from anywhere else.

Identity

No cookies, no IP by default

IDs are random and kept in browser storage, not cookies. IP addresses aren't stored unless you turn that on for a source.

Consent

Opt-out or opt-in, and Global Privacy Control

The snippet the app gives you collects by default and honours Global Privacy Control: a browser that sends the signal isn't tracked. Switch a source to opt-in and nothing is stored or sent until your consent banner calls optIn. A visitor who opts out has their IDs cleared from the browser and stays opted out. The consent guide has the details.

AI features

The AI model gets totals only

Ask, “Why did this change?” and the friction investigator send the AI model aggregates only. Person, session and visitor IDs and individual event rows are left out, email addresses and ID-like values are redacted, and a group of fewer than five people is reported as “<5”. The model provider is Anthropic, and the question you type is sent along with those totals.

05 · The application

HTTPS, browser protections and dependencies.

Transport

HTTPS only

The app is served over HTTPS and tells browsers to refuse plain HTTP for two years (HSTS). Requests that change something must come from the app's own address.

Browser

A strict content policy

A Content Security Policy allows scripts only with a code that changes on every response. The app can't be embedded in a frame on another site, and it asks for no camera, microphone or location access.

Dependencies

Checked every week

Dependabot checks our dependencies weekly and opens security updates. Every change is built from a locked dependency list and has to pass linting, type checks and tests.

06 · Your data

Retention, export, deletion and reporting a problem.

Retention

How long data is kept

Event history is kept for 12 months on Growth and 24 months on Pro. Heatmap captures expire after 30 days. The Realtime view covers the last 30 minutes.

Export

Download your data

Export your account data from your settings. An organization's data can be exported too. An export file is kept privately for 24 hours, and its download link works for 10 minutes and only in your session.

Deletion

Thirty days to change your mind

Delete your account or an organization from settings. Collection stops when you ask, and an organization's API keys and webhooks are switched off at once. You can restore it for 30 days, after which it is removed for good. Read the privacy policy for the details.

Disclosure

Report a vulnerability

If you think you've found a security issue in ClickClacks, email us what you found and how to reproduce it, before sharing it anywhere else. A person reads every report.

Start hearing your clicks.

Install one script tag and see your first report in minutes.

About 5 KB · pageviews, clicks and scroll depth, automatically