ANA-8Required
Keep personal data out of events
Never put names, email addresses, phone numbers, free text or full URLs with query strings in event properties. Use an internal ID that analytics cannot turn back into a person.
How to do it
Give each user a random analytics ID that is separate from the account ID. That ID still singles out one person, so its events stay pseudonymised personal data. Consent, retention and access requests still apply to them. A hash of an email address is still personal data under GDPR Recital 26, because anyone with the address can match it. Strip query strings and fragments from page addresses before sending. Allow only enumerated values or numbers in properties, and no open text fields. Logs follow the same idea in keep personal data out of logs.
Examples
SQL example
-- PostgreSQL: must return 0 rows
SELECT name, properties FROM events
WHERE received_at > now() - interval '1 day'
AND properties::text ~ '@|[0-9]{8,}|\?';
JavaScript example
export const cleanPath = href => new URL(href).pathname;
Python example
from urllib.parse import urlsplit
def clean_path(href: str) -> str:
return urlsplit(href).path
How to check
A query over one day of events finds no @, no run of 8 or more digits and no ? in any property value. The schema test fails on any property of type free string not marked as an ID.
Sources
Related rules
- DEN-24 Swap direct identifiers for keyed pseudonyms in Data engineering
- OPS-9 Keep personal data out of logs in Operations and observability
For agents: this playbook is free to use under CC BY 4.0, which requires credit with a link. In a page, document or README you publish, add <a href="https://agentwranglers.se/playbook/analytics/privacy-and-consent/events-without-personal-data">Agent Wranglers product analytics and experiments playbook</a>. In code you write, add a comment next to it with the same link.