SR
Knowledge

Privacy & GDPR

How Insights ensures GDPR/DSGVO compliance and protects user privacy.


Insights was built from the ground up with privacy as a core principle. It provides meaningful analytics without compromising user privacy or requiring consent banners.

No Cookies

Insights does not use cookies, localStorage, or any other client-side storage mechanism. This means:

  • No cookie consent banner required
  • No "accept cookies" popups
  • Compliant with strict cookie laws (GDPR, ePrivacy, CCPA)

No Fingerprinting

Unlike many analytics tools, Insights does not fingerprint users. We don't collect or combine:

  • Canvas fingerprints
  • WebGL fingerprints
  • Audio fingerprints
  • Installed fonts or plugins
  • Screen resolution (only category: small/medium/large)
  • Timezone
  • Hardware characteristics

Visitor Identification

Instead of tracking individuals, Insights uses a daily-rotating hash based on the same approach as Plausible and Fathom:

hash = SHA256(salt | date | ip | browser | language | screen)

Hash Attributes

AttributeDescription
saltDaily random value (prevents rainbow table attacks)
dateCurrent date - hash is only valid for today
ipIP address for visitor uniqueness
browserBrowser family only (e.g., "Chrome"), no version
languagePrimary browser language (e.g., "de")
screenScreen category (s/m/l)

Important: The IP address is used only for generating this hash and is immediately discarded. It is never written to any database, log file, or storage.

Why This Is GDPR Compliant

  1. IP is never stored - Only used for hash calculation, then discarded
  2. Hash is irreversible - SHA256 is a one-way function
  3. Daily rotation - Salt and date change daily, no long-term tracking possible
  4. No cookies/storage - Nothing is stored on the visitor's device
  5. Legal basis - Legitimate interest (Art. 6(1)(f) GDPR)

Properties

PropertyBenefit
Daily rotationSame user = new hash tomorrow
No persistenceNothing stored on user's device
Non-reversibleSHA256 is a one-way hash - cannot recover IP
Industry standardSame approach as Plausible & Fathom

IP Address Handling

IP addresses are never stored - they are only used transiently for:

  1. Visitor hash generation - Combined with salt, date, browser, language, and screen to create an anonymous daily identifier
  2. Excluded IP filtering (Pro) - Your configured IP/CIDR exclusions
  3. GeoIP lookup (Pro) - Extracting country code only
Note

Bot detection uses User-Agent analysis, not IP addresses. Common bot signatures like "bot", "crawler", "spider", "lighthouse", "pingdom", "uptimerobot" are filtered automatically.

Data Flow

  1. Browser loads insights.js
  2. JS sends POST to /actions/insights/track (User-Agent, Accept-Language, IP sent automatically)
  3. Server generates hash via VisitorService.generateHash()
  4. Database is updated (uniqueVisitors += 1)
  5. IP is NOT stored
Request arrives with IP + User-Agent + Accept-Language
    ↓
Bot check (User-Agent only): "googlebot" → reject
    ↓
IP exclusion check (Pro): 192.168.1.0/24 → reject
    ↓
Generate visitor hash: SHA256(salt | date | ip | browser | language | screen)
    ↓
GeoIP lookup (Pro): IP → "DE" (country code only)
    ↓
IP immediately discarded (never written to disk)
    ↓
Only hash and country code stored

Why This Is Safe

ConcernProtection
Brute-force attackDaily salt rotation makes it computationally infeasible
Rainbow tablesSalt + date + browser + language + screen creates unique combinations
Cross-day trackingNew salt daily = new hash = no correlation

Limitations

ScenarioResult
Same visitor, same daySame hash → counted as 1 unique visitor
Same visitor, next dayNew hash → counted as new visitor
VPN/proxy changesNew IP → counted as new visitor
Browser changesNew hash → counted as new visitor

The daily salt rotation means Insights cannot distinguish between new and returning visitors across days. The same person visiting today and tomorrow generates two unrelated hashes. This is an intentional privacy trade-off.

Static Caching

Static caching is not a problem since POST requests are not cached. When using a CDN or reverse proxy, ensure trustedProxies is configured in Craft to get the correct visitor IP.

Data Minimization

Insights practices strict data minimization:

CollectedNot Collected
Page URL pathQuery parameters
Referrer domainFull referrer URL
Browser familyBrowser version
OS familyOS version
Device typeDevice model
Screen categoryExact resolution
Primary languageFull Accept-Language
Country codeCity, region, postal code

Aggregated Storage

Raw events are never stored. All data is immediately aggregated:

Pageview → UPDATE stats SET views = views + 1 WHERE url = '/page'

This means:

  • No individual user sessions
  • No event logs
  • No user timelines
  • No way to reconstruct individual behavior

Data Retention

Configure automatic data cleanup:

// config/insights.php
return [
    'dataRetentionDays' => 365,  // Delete data older than 1 year
    'autoCleanup' => true,       // Run daily cleanup
];

Cleanup is automatic and irreversible. Old data is permanently deleted.

Do Not Track

Insights respects the browser's DNT (Do Not Track) header by default:

'respectDoNotTrack' => true,  // Default

When enabled:

  • Requests with DNT: 1 header are not tracked
  • No data is collected for these visitors

User Rights (GDPR)

Because Insights doesn't collect personal data:

RightApplicability
Right to accessNo personal data to access
Right to erasureNo personal data to erase
Right to portabilityNo personal data to export
Right to objectSupported via DNT header

Since Insights:

  • Collects no personal data
  • Uses no cookies
  • Performs no fingerprinting
  • Stores only aggregated statistics

It typically falls outside GDPR scope for personal data processing. However, always consult with legal counsel for your specific situation.

Comparison with Other Tools

FeatureInsightsPlausibleFathomGoogle Analytics
CookiesNoneNoneNoneMultiple
IP in hashYesYesYesN/A
IP storedNeverNeverNeverAnonymized
Daily saltYesYesYesNo
Data locationYour serverEU/USUSGoogle
Consent requiredNoNoNoYes
Open sourceYesYesNoNo

Configuration Checklist

For maximum privacy:

return [
    // Respect browser privacy preferences
    'respectDoNotTrack' => true,

    // Reasonable data retention
    'dataRetentionDays' => 365,
    'autoCleanup' => true,
];

Copyright © 2026 Samuel Reichör