Most teams build consent backwards. They start with the banner - the colours, the copy, where the buttons sit - and treat everything behind it as plumbing to wire up later. But the banner is the one part regulators rarely fine you for. The fines land on what happens after the click: the signal that never reached the ad platform, the app SDK that fired before anyone agreed, the withdrawal that updated a screen but stopped no processing. A consent system isn’t a banner. It’s a small distributed system for capturing a decision, storing it as evidence, enforcing it everywhere, and being able to prove all of it months later.
Consent Is Four Jobs, Not One
A consent system has to do four distinct things, and most broken implementations are missing two or three of them without realising it. It has to capture a decision - granularly, per purpose, on whichever surface the user is on. It has to store that decision as a durable record, not a single true/false flag. It has to enforce the decision, meaning the analytics, the ad tags, the SDKs, and the downstream processing actually change behaviour based on it. And it has to prove the decision later, reproducing exactly what the user saw and agreed to. Capture is the part everyone builds. Store, enforce, and prove are the parts that get skipped - and they’re the parts that get tested.
The four jobs - and where each one breaks
| Job | What it has to do | Where it breaks in practice |
|---|---|---|
| Capture | Granular choice per purpose, on web and in-app, with reject as easy as accept | A single accept/reject; the in-app flow gates nothing; reject buried |
| Store | A consent record per decision: subject, purpose, scope, notice version, timestamp, surface | A boolean column overwritten on every change, with no history |
| Enforce | Tags, SDKs, and server-side processing actually read and obey the stored state | Banner sets a cookie but scripts fire anyway; app SDKs init on launch |
| Prove | Reproduce on demand what was shown and chosen, six months later | No notice version stored; the record can’t be tied back to a session |
One Source of Truth, Many Surfaces
The single decision that shapes everything else is where consent lives. The mistake is letting each surface own its own copy - the website remembers one thing in a cookie, the iOS app another in local storage, the backend a third in the user row - and trusting them to stay in sync. They won’t. The architecture that holds up is a single consent service that every surface writes to and reads from: the web CMP, the mobile SDKs, and the backend all defer to one authoritative store keyed to the user - or, before login, to a stable anonymous identifier you later stitch to the account.
This is harder than it sounds, because the same person shows up as different identities - a logged-out web visitor, a logged-in app user, an email recipient - and their consent has to follow them across all of it. If a user accepts on the website and later logs into the app, the app must already know. If they withdraw in the app, the website and every downstream system must find out. Consent that doesn’t travel with the person is consent you can’t actually honour.
App: Consent Has to Hold the SDKs Back
Mobile is where consent systems quietly leak. The default behaviour of most analytics, attribution, advertising, and crash-reporting SDKs is to initialise the moment the app launches - before the user has seen a single screen, let alone made a choice. A compliant app has to invert that: nothing that processes personal data starts until consent is captured, and SDK initialisation is gated behind the stored state, not behind the app’s launch. Apple’s App Tracking Transparency prompt is not this - ATT is a separate, platform-level permission, and treating it as your GDPR consent leaves most of your processing ungoverned. The consent a user gives in-app also has to reach your backend, so that server-side processing and anything you forward to processors respect it too. First launch, offline state, and app updates each need a defined default - and the safe default is always no consent until proven otherwise.
In Case C-604/22, the Court of Justice of the European Union ruled that the encoded string adtech uses to carry a user’s consent choices - the TC String - is itself personal data when it can be linked to an identifier such as an IP address, and that the body defining the framework could be a joint controller for it. A Belgian court confirmed the position in 2025. The implication reaches well past adtech: the moment your system records what a person consented to, that record is regulated personal data in its own right. A consent system isn’t a neutral logbook sitting outside the regulation - it’s processing that needs its own lawful basis, retention, security, and access handling. Many teams build the consent store as an afterthought and forget it’s in scope for exactly the rules they were trying to comply with in the first place.
Final Thought
A consent system is judged on its weakest surface. You can have an immaculate cookie banner and still fail because an Android SDK fired before the user chose, or because withdrawal stopped at the website while the email platform kept sending. The regulation treats consent as one continuous obligation across everywhere you process - capture it cleanly, store it as evidence, enforce it on every surface, and keep the proof.
The test that cuts through it: pick any user and any purpose, and answer four things without engineering having to dig - what did they choose, on what version of the notice, is it still being honoured everywhere right now, and would withdrawal actually stop the processing. If any answer needs a meeting, you have a banner, not a consent system.
Frequently Asked Questions
No. The banner is the visible ten percent. A compliant consent system also has to store a defensible record of each decision, enforce that decision so tags and SDKs actually obey it, and be able to reproduce what was shown and chosen months later.
Yes. Article 7(3) requires that withdrawal be as easy as granting consent — in the UI and in the backend behind it. A one-click accept and a buried, multi-step withdrawal fails the test.
Under Article 7(1) you must be able to prove consent: who consented, when, to what purpose and scope, against which version of the notice, and on which surface. A single boolean column overwritten on every change is not a record.
Google's requirement, in force since March 2024, that sites using its ad and measurement products signal user consent for EEA traffic. Without it, ads and measurement on EEA users are affected.