To prove consent, log who consented, when, the exact wording and version they saw, how they gave it, the purposes covered, and any later withdrawal. GDPR Article 7 says a controller must be able to demonstrate that consent was given, so a boolean column on the user table is not enough.
What the regulator expects to see
Article 7(1) says "the controller shall be able to demonstrate that the data subject has consented." The UK Information Commissioner's guidance spells out the practical records: who consented, when, what they were told, how they consented, and whether and when they withdrew. It also says records should be as granular as the consent itself.
That points to an append-only event log, not a mutable flag.
A workable schema
One row per consent event:
event_id, a unique ID.subject_id, the account or pseudonymous visitor ID.purpose, one value per purpose, such asproduct_emailoranalytics.action, eithergrantedorwithdrawn.occurred_at, a UTC timestamp from the server.text_version, a reference to the exact consent wording and linked privacy notice version.channel, such as web form, mobile app or support agent entry.ui_context, the form or screen identifier, so you can reproduce what the person saw.
Do not store more personal data than needed. The log itself is personal data, so avoid raw IP addresses and full user agent strings unless you have a clear reason.
Keep the wording versioned
If you cannot show what the person was told, a timestamp proves very little. Store each consent text and privacy notice version in version control or a table, with an effective date, and reference it from the event. When copy changes, create a new version. Never edit a published version in place.
Current state is derived
Compute the current state by reading the latest event per subject and purpose. Expose it through one function that every system calls. Do not copy the flag into five services, or withdrawal will reach only some of them.
Granularity and defaults
Record separate events for separate purposes. A single "I agree" that bundles marketing, analytics and sharing makes it hard to show that consent was specific. Also record unticked boxes by default: no event means no consent.
Retention of the log
Keep consent evidence for as long as you rely on the consent, as the ICO puts it. After that, delete or reduce it, but check whether you need a short suppression record, for example to avoid emailing someone who opted out.
Integrity
The ICO notes that online, a cryptographic hash can support integrity. Hash the event contents and chain or sign batches if you expect disputes. This is optional for small teams, helpful for regulated ones.
Quick check
Can I just store consent_given = true?
That shows a state, not proof of what the person saw or when. Keep dated events and the wording version.
Does consent logging apply when I rely on a contract?
No. It is needed where consent is your lawful basis. Other bases need other records.
Sources
Last reviewed: 19 October 2026.