Zero cookies. Zero browser storage.
In default mode the tracker writes nothing and reads nothing on the visitor's device — no cookies, no localStorage, no sessionStorage, no IndexedDB. A proxy-sealed storage asserts zero accessor hits.
The legal moat
Every analytics platform asks you to balance insight against intrusion. Observer is architected so the balance is unnecessary: the default mode stores nothing on the visitor's device, identity rotates daily, and small samples are suppressed at query time. Privacy here is not a policy — it is math.
This website
Scope. The rest of this page describes the Observer product: what it does when a customer runs it on their own server. This section describes what this website, observer.castomo.com, does.
Analytics: Observer. We count visits with Observer, our own analytics, run by Castomo on its own server in Frankfurt. It sets no cookies and stores nothing on your device. For each page you open it records: the page address (of any query only campaign tags such as utm_source) and title, the site you came from, your browser, device type and operating system, your browser language, a rough screen-size bracket, how long the page was actively open, how fast it loaded, any script error, and — as totals — where people click and how far they scroll. It takes no recording of your screen and reads no keystrokes.
Your IP address is used for a moment, together with your browser, to make a code that changes every day and is different on every site. The IP address itself is never stored, and the server that delivers Observer keeps no access log. The code lets us count one visitor once a day, and it cannot be used to link a visit to visits on other days or other sites. Raw records are deleted after 24 hours; only totals are kept, for 25 months. If your browser sends Do Not Track or Global Privacy Control, Observer sends no visit data.
We do this because we have a legitimate interest in knowing how our pages are used (Article 6(1)(f) GDPR). You can object at any time: hello@castomo.com.
Chat assistant. Every page has a chat button run by Castomo (chat.castomapi.com, servers in Amsterdam). Until you open the chat, the button stores nothing on your device and starts no conversation; loading the page only fetches the button's settings from our chat server, which, like any web server, records the request, including your IP address, in a rotating log that is overwritten as it fills.
When you open the chat, the chat window saves a visitor code and a few settings in your browser's local storage, and our server creates a visitor record: the code (kept only as a hash), a hash of your IP address, your browser type, language and time zone, the page you were on and where you came from, and everything you type — plus your name, e-mail or phone number only if you give them.
The assistant is an AI, and it says so. Its answers are written by AI models run by OpenRouter (Google Gemini) and OpenAI, which receive what you type in order to reply; after a conversation ends the same text is sent to a model again to write a short summary. A person on our team can read the conversation and take it over. These providers may process data outside the European Economic Area.
We keep a visitor's record and conversations until 180 days after their last visit, then delete them. You can ask us to delete them sooner: hello@castomo.com. Please do not type anything you do not want us to have.
The claims — tested, not aspirational
These are not values we intend. They are invariants the CI suite checks on every build — including a 6-spec browser privacy suite that runs the tracker in a real browser with storage proxies and network recording.
In default mode the tracker writes nothing and reads nothing on the visitor's device — no cookies, no localStorage, no sessionStorage, no IndexedDB. A proxy-sealed storage asserts zero accessor hits.
Identity is derived server-side from what the browser already sends (IP + user agent), hashed with an HKDF key that rotates at midnight UTC. Yesterday's hash cannot be joined to today's.
Each site gets its own salt. Your blog cannot correlate with your shop — enforced by construction, not by policy.
The IP exists for milliseconds in collector memory — geo lookup and HMAC input — then it is gone. Never logged, never serialized; a CI invariant checks the collector never marshals it.
Every dashboard row, export and share link suppresses data below 5 sessions. Small-sample re-identification is blocked at query time, not by convention.
No canvas, WebGL, audio or font probes. A static audit fails the build on any violation — the SDK physically cannot grow a fingerprinting bone.
Self-hosted on your infrastructure. No third-party endpoint, no subprocessor chain, no international transfers — the data never leaves the machines you own.
Logins, config changes, key creation, alert firings — every action is append-only logged and visible on the Privacy Posture page.
Do Not Track, Global Privacy Control and observer('optOut') silence the SDK unconditionally — verified by tests asserting zero beacons and zero storage.
How identity works
Most analytics tools give a visitor a persistent ID. Observer derives an anonymized device-day pseudonym server-side: HMAC-SHA256 over what the browser already sends, keyed by an HKDF key that rotates at midnight UTC, salted per site. A visitor is "someone, on this device, today" — and nothing more.
Nothing is stored on the device. Nothing to clear, nothing to refuse, nothing to consent to.
The input is what every HTTP request already carries — IP and user agent — used for milliseconds and discarded. No probes.
Key rotation is cryptographic, not administrative: joining Monday's visitor to Tuesday's requires the old key, which no longer exists anywhere.
Query-time protection
Dashboards, CSV exports and public share links all pass through the same post-filter: any row describing fewer than 5 sessions is suppressed. A quietly-read internal page cannot be re-identified by filtering your way down to one visitor.
| Path | Views | Devices | Engaged | Status |
|---|---|---|---|---|
| / | 9,342 | 6,118 | 2:58 | exact |
| /pricing | 4,187 | 3,206 | 3:24 | exact |
| /blog/cookieless-analytics | 2,905 | 2,144 | 4:02 | exact |
| /internal/roadmap-2026 | n = 3 — below the k-anonymity floor of 5 | suppressed | ||
The same floor applies to every export, every API response and every public share snapshot. "Estimated" device counts carry an honest badge — NAT collisions undercount, IPv6 churn fragments, so devices are estimated device-days, never "unique users".
The consent-free claim, worded legally
Based on our self-assessment, Observer meets the criteria established by the CNIL and can be implemented without requiring user consent when correctly configured.
CNIL self-assessment wording — the template we ship for your privacy policySelf-hosted · cookie-less · no consent required when correctly configured (CNIL self-assessment wording) · sessions are pseudonymous · aggregate statistics are anonymous.
"GDPR compliant", "certified", "CNIL-approved", "anonymous users", "100% anonymous". We show you the architecture and hand you the tests — you verify, you decide.
The per-site Privacy Posture screen: exactly what is collected, stored where, for how long, under which tier and legal basis — plus the live audit feed.
Per-site, server-enforced
Tiers are enforced by the collector, not the snippet — the tracker cannot upgrade itself. DNT and GPC silence the SDK unconditionally at every tier.
| Tier | Browser storage | What it unlocks | Consent | Identity model |
|---|---|---|---|---|
| T0 — Strict (default) | Nothing — no write, no read | Everything: sessions, heatmaps, frustration, CWV, funnels | No banner | Daily-rotated HMAC |
| T1 — Session | sessionStorage only (tab-scoped) | Stable sessions across reloads; reliable funnels and paths | Documented legal basis | Per-tab sid + HMAC |
| T2 — Consented | + localStorage visitor id (13 months, never auto-extended) | Cross-visit continuity; session replay (sampled, masked) | Explicit opt-in | Visitor vid + HMAC |
| T3 — Disabled | Nothing | Nothing — SDK inert, collector rejects | Kill-switch | None |
The T2 visitor id expires 13 months after creation. Visits do not extend it — that would defeat the purpose, and CNIL guidance is explicit about it.
Before consent, T2 collection is zero beacons, zero storage, zero cookies — asserted by the consent-gate test in the browser suite.
T2 replay applies maskAllInputs in the browser, honors obs-mask / obs-block / obs-ignore, and disables canvas and font capture.
The page you show a lawyer
Every site in your registry carries a live posture view: tier, captured fields, retention state, consent requirement, legal-basis reference and the recent audit entries. Not a PDF from the sales team — the actual configuration, read from the control plane, for the site in question, right now.
Point your DPO at it. It answers the only three questions that matter: what is collected, for whom, and for how long.
The refusals
Deleting these from a roadmap is easy. Observer never had them on one — they contradict the architecture, and the static audit keeps them out of the SDK.
No global visitor graph. Per-site namespaces make correlation between your properties impossible — even for you.
No canvas, WebGL, audio or font probes. The mouse-move heatmap is deliberately excluded too — movement profiling is the least privacy-friendly heatmap type.
No audience exports, no pixel syncs, no campaign matching. If a feature would require sending visitor data to a third party, it cannot exist in Observer.
Form analytics counts focus and fill events. Field labels are hashed; values are never read, never sent, never stored.
Not in the event store, not in logs, not in exports. A CI invariant fails the build if the collector ever marshals the IP into a durable form.
Raw events TTL out at 24 hours by schema. What persists is 25 months of k-anonymized rollups — aggregates, not behavior traces.
Honest limitations — part of the trust story
We publish these because every analytics tool has limits, and most hide them. Ours are the direct consequence of the architecture — and we think that trade is worth it.
FAQ
No — in the default mode (T0), Observer stores nothing on the visitor's device and reads nothing from it. The CNIL self-assessment confirms this posture. If you enable T1 or T2 (session storage or visitor id), you need a documented legal basis or explicit consent.
Observer derives an anonymous identity server-side from what the browser already sends (IP + user agent), hashed with a key that rotates at midnight UTC. Each day gets a fresh key, so yesterday's identity cannot be linked to today's. This is not a cookie, not fingerprinting, and not persistent.
No. Observer shows anonymized sessions — device-day pseudonyms. Timelines show what was done, never who did it. There are no user profiles, no cross-site identity, and no persistent visitor tracking in the default mode.
Yes. Observer runs on your hardware — ClickHouse, collector, API and dashboard, all in Docker or bare Node.js. No third-party endpoint, no subprocessor, no data leaves your infrastructure.
Those are traffic counters. Observer adds the entire behavior layer — session timelines with tab-split lanes, heatmaps, frustration detection, form drop-off, CWV RUM — plus the privacy architecture none of them ship: k-anonymity, an audit log, a privacy-posture page and rotating identity namespaces.
Observer is designed for GDPR compliance by architecture — data minimisation, purpose limitation, storage limitation. In the default mode, no personal data is stored. We provide CNIL-compliant self-assessment wording for your privacy policy. We never claim "GDPR certified" — we show you the architecture and let you verify.
Observer is self-hosted. The only cost is your server — roughly €60–90/month for about 60 million events per month. No per-traffic, per-site, per-seat or per-feature charges. Competitors charge $1,200–$2,950+/month at the same volume.
Because the tier is enforced by the collector, server-side. A modified or misconfigured snippet cannot enable storage, extend retention or start recording — the collector rejects events that the site's tier does not allow.
Yes — and Global Privacy Control, and the explicit observer('optOut') call. All three silence the SDK unconditionally: zero beacons, zero storage. This is asserted by automated browser tests.
The browser privacy suite — cookies, storage, PII scrubbing, consent gate, GPC silence — runs against your deployment during onboarding, and the report goes to your DevOps team.