Cookie consent (GDPR) — design¶
How Raklet asks for, stores, and respects cookie consent for non-essential analytics/marketing trackers. Engineering reference (tracker map, code paths): GDPR cookie consent — implementation.
- Ticket: ENG-276 (Security milestone), split from ENG-273
- PR: #14330
- Shipped: 2026-06 · own-build, no vendor
Why¶
A customer security review (Zachęta termination notice, 2026-06-25) flagged that
Raklet loaded analytics/marketing trackers — Google Analytics, Mixpanel, Clarity,
HubSpot, Intercom, org-injected scripts — with no consent mechanism at all
(only an environment != "local" check). Under GDPR/ePrivacy, non-essential
trackers need prior, opt-in consent, must be off by default, and consent
must be withdrawable as easily as it was given. ENG-273 removed Mixpanel and
its public-IP injection; ENG-276 adds the consent layer for everything else.
Decisions¶
Build vs buy → own-build. Third-party CMPs (Cookiebot, CookieYes, Osano) price per-domain or per-pageview, which fights Raklet's multi-tenant model (every org permalink + custom domain is a separate "site"); they also can't see behind our auth to gate manager-only trackers, and add yet another third-party script — the exact thing the complaint was about. A lightweight own-build banner slots into the existing server-rendered tracker partials, costs nothing recurring, and gives full control. ~3-4 days vs an enterprise CMP quote.
Two categories, default-deny. Non-essential trackers are split into Analytics (GA, RakletAnalytics, Clarity, Mixpanel-until-removed) and Marketing (HubSpot, Twitter, Facebook, Bing, Intercom). Strictly-necessary cookies are never gated. Nothing non-essential loads until the visitor opts in.
Per-org portals, shared Raklet properties. Each organisation's member portal
is its own data controller, so portal consent is per-org (host-only cookie).
Raklet's own login + admin are shared on raklet.com (like www), so one choice
spans them. Strict per-org isolation that also ignores the Raklet-level cookie was
considered and deliberately not taken (accepted nuance documented in the eng ref).
What shipped¶
Consent banner — on every user-facing surface (portal, admin SPA, login, legacy admin + Manager/Login areas). Accept all / Reject non-essential / Manage preferences.

Per-category preferences — expand to toggle Analytics / Marketing individually; Strictly-necessary is locked on.

Withdraw anywhere — after a decision a persistent "Cookie preferences" entry point stays on every page, reopening the panel (withdraw as easily as granted).

Privacy settings card — logged-in members manage cookies from
Settings → Privacy, alongside the existing Visibility and Communication consent
cards.

Deliberately cut / deferred¶
- Org-injected CustomJs left ungated — it can carry operational code, so auto-gating it risks breaking tenant sites. Needs a product call (tenant responsibility vs gate vs per-org "is-tracker" flag).
- Translations — English now; other locales fall back until translated.
- DPA / §12.3 alignment — confirm the tracker classification matches our DPA.
- Mixpanel removal owned by ENG-273 / #14325.