Skip to main content
Woop Technology
All references
Technical Case Study | Security & Independence

A consent architecture built for our projects, for security and data sovereignty

For our web applications we built consent management ourselves instead of outsourcing it to an external consent platform. Function, design and behaviour are ours to define; consents and their logs stay on our own infrastructure – with no third-party script in the load path and no recurring fees.

Interface
Banner and settings in the project's own design
Consent engine
State, versioning, registry, gating
Data source
JSON, API or CMS – interchangeable
Three separate layers: the engine in the middle owns how the system works, the data source below it is interchangeable, and the interface above belongs to the individual project.
Project facts
Type
Technical case study
Module
@woop-technology/consent
Reference projects
Status
In use | under continuous development
Integration
React | Next.js App Router
Distribution
Private package registry
Focus areas
  • Consent architecture
  • Data sovereignty
  • Google Consent Mode v2
  • Cookie registry
  • versioned consent
  • script gating
  • interchangeable data sources
  • multilingual content
  • project-specific interfaces
  • server-side logging
Starting point

Why we developed our own consent management

Web applications often embed external services such as analytics, maps, videos or appointment booking. That creates additional data flows – and two questions: under which conditions these services may be loaded, and what happens to the data once it has left our own server.

The obvious answer would be an external consent platform. For us it would have brought three things we did not want: another monthly bill, a consent system that reaches only as far into the application as the vendor allows – and our visitors' consent data on someone else's servers.

That is why we developed our own consent management: as an integral part of our application architecture, reusable and adaptable – and built so that the data stays exclusively on our own infrastructure.

The solution had to
  1. 01Manage consents and storage values centrally, without an external vendor
  2. 02Enable services depending on consent
  3. 03Process consents and logs exclusively on our own infrastructure
  4. 04Support different languages, data sources and interfaces
  5. 05Be reusable, without additional fees per month or project

The result is a standalone consent engine that is used today as a shared technical module in our projects.

Independence & Security

Three things we don't hand over

An external consent platform adds a vendor: its own scripts, its own configuration, its own servers and a recurring fee. Our own engine runs together with the application instead, within the same infrastructure and with the same tools.

What that means in practice comes down to three points.

Costs
No licence per domain, per page view or per month. The costs arise once in development and continuously in maintenance.That is sustainable because the same building block runs in several projects.
Control
Function, data basis, design and behaviour are ours to define – right into the application code, which can query the consent state directly.Nothing ends where a vendor's feature set ends.
Data
Configuration, consents and logs live on our own servers. No third party stores, processes or sees our visitors' decisions.
The consent function needs no external CMP

The consent configuration and the central engine are part of the application itself. No external CMP provider is therefore required for the consent system.

That means
  • no additional CMP script
  • no external network request for the consent function itself
  • no third-party consent interface
  • no additional platform dependency solely for managing consent

Consent-dependent services remain separate from this and load only once the required consent is in place.

Less third-party code, less attack surface

An external consent script runs with the same privileges as the page itself and is loaded from a third-party server. Every version the vendor ships thus becomes part of the website without being reviewable in detail.

With established vendors that is usually unproblematic. We still prefer to know the code that runs on our pages: our own engine is versioned, reviewed and deployed like the rest of the application code.

The logging endpoint
  • accepts requests from the site's own origin only
  • checks every request for complete and permitted fields
  • truncates the IP address before it is stored
  • sits on a fixed path for which the upstream firewall can keep its own rules
Consents and logs live on our own servers

No further vendor is involved in managing consents. A visitor's decision takes effect in the application and is logged on the same server the application runs on – where the project's other data is processed as well. That applies to every project using the engine: decisions are logged locally in the container of the respective application.

Which other external services a specific project uses, and which data is transferred in the process, is defined and documented project by project, independently of this.

Architecture

Three separate layers for logic, data and presentation

The consent system separates the central functional logic from project-specific data and the visible interface.

As a result, the same technical foundation can be used in different applications without having to reimplement consent state, versioning or script gating for every project.

The module ships with a standard interface that the project styles or replaces entirely. That is how the same engine runs on an art platform and on a corporate website, even though the two interfaces differ in design.

Consent engine
The central engine takes on the functions that stay the same across projects:
  • consent state
  • version check
  • cookie registry
  • script gating
  • two-click solutions
  • withdrawal
  • clean-up of declared storage values
  • Google Consent Mode v2
The shared functional logic is maintained centrally and provided as a reusable module.
Data source
The engine receives the project-specific information through a defined interface. This includes, among other things:
  • consent version
  • categories and services
  • cookies and other storage values
  • texts per language
  • script configurations
The bundled implementation reads JSON files in the project. A headless CMS or your own API is connected by implementing the same interface – the engine is unaffected.
Interface
Banner and settings dialog are designed for the respective project. The interface receives the data it needs and a fixed set of actions from the central engine.This means the visual appearance can be adapted to each project without having to change the underlying consent logic.

Everything on our own infrastructure.

0External vendors
0External CMP scripts
Reference project | Woop Art
3Consent categories
4Services
7Cookies
2Languages
Reference project | This website
3Consent categories
4Services
7Cookies
5Languages

The figures under the reference projects apply to their respective configuration. Categories, services and cookies are freely configurable.

One shared module instead of project-specific one-offs

The consent engine is provided as its own package via Woop Technology's private package registry. Versions and changes are managed centrally; each project pins the version it needs and adopts updates on its own schedule – so different projects can run different versions at the same time.

Every new project adds four areas:

01Data
Categories, services, storage values and texts.
02Persistence
Where the logs of consent decisions are stored.
03Integrations
Analytics and other consent-dependent services.
04Design
Default interface or custom banner and settings components.

Consent state, versioning, registry, script gating and withdrawal come from the shared module. Improvements to the engine can be carried over to several projects through versioned updates.

What the engine brings, what the project decides

  1. 01Enginecategory-based consent, versioning, revocation, cookie cleanup, script gating, Google Consent Mode v2
  2. 02Projectdata source (JSON, API or headless CMS), languages, interface (standard UI or own components), integrations (hooks, two-click solutions)
  3. 03Persistenceconsent cookie in the browser, server-side logging, truncated IP addresses
  4. 04Stack & operationsReact, TypeScript, Next.js App Router, dependency injection, private package registry, validated inputs

What a consent stores in the browser

Simplified: here every change applies immediately, in the real dialog only on saving – and every save is logged server-side. Fields and version match the engine of this website. Checked on 21 September 2026 in a test environment: the tested analytics integration only loads after the corresponding consent.

Two clicks before an external service loads

Not every consent belongs in the banner. For embedded services such as appointment booking, the engine asks for it where the visitor actually wants to use the service.

First click: notice and new label. A click next to it closes the notice without Google having been loaded.
Recording of this website's home page. Checked on 23 September 2026: on page load and after the first click, no request goes to an external server; all requests to Google follow the second click.
  1. 01

    First click: the notice

    The button shows which provider would be loaded and which data would be transferred. Its label changes to “Load Google Calendar”.

  2. 02

    Second click: loading

    Only now are the provider's script and stylesheet included and the booking opened. Until then, no request reaches Google.

  3. 03

    No detour via the banner

    Visitors do not need to enable a category in the consent settings. The decision is made at the service itself, for that service alone.

The components for this live in the same package as the engine: ready-made for Google Calendar and Calendly, and available for other services through a shared base component.

The consent ID is one click away

Every decision is logged on the server, but it can only be found unambiguously through its consent ID. A dedicated component puts that ID within easy reach of visitors.

The ID sits in the consent cookie, where nobody sees it without developer tools. Yet it is the only unambiguous way to the entry on the server, because the IP address is stored only in truncated form.

The component displays the ID and copies it with one click. With a question, a complaint or an access request, visitors simply send it along, and the entry is found without follow-up questions – with time, version and selection.

The component sits in the privacy policy of the respective website and also leads straight to the consent settings from there.

Consent Status: Not set

Your current Consent ID

This unique ID is stored locally in your browser and pseudonymized on our server to prove your privacy choice. If you have questions or complaints about your consent, please include this ID – it lets us find the matching record unambiguously.

No choice made yet

The component comes ready-made with the consent package. Like the banner and settings dialog, it can be designed freely: the logic stays in the package, the project decides the look – here that of this website.

Data, languages & interface

The consent logic is not tied to a particular data source

The consent engine does not read its data itself but through a defined interface. Where the data comes from is decided by the implementation of that interface – the engine stays the same.

Default: files in the project
The bundled implementation reads versioned JSON files that ship with the source code. The configuration needs no network request.
Editorial CMS
Implement the interface for a headless CMS, and editors maintain texts, services and cookies there – without any change to the engine.
Your own system via API
Your own CMS or a central service can be connected through its API in the same way – for example to maintain consent data for several applications together.

Technical definition and translations remain separate

Cookie names, identifiers, categories and storage durations are defined once. The texts in the banner and settings dialog, by contrast, exist in every language; visitors see them in the language they have chosen:

  • category labels and descriptions
  • service information and cookie purposes
  • information on data transfers
  • banner texts and buttons
  • screen reader labels

Shared logic, different interfaces

The engine offers a default interface that can be replaced in whole or in part by project-specific components.

A project can
  • adopt banner and settings dialog unchanged
  • design only the banner itself
  • replace only the settings dialog
  • implement both interfaces individually

Consent state, versioning and withdrawal remain centrally managed throughout.

Consent banner in the design of the reference project
The banner blends into the website's design.
Settings dialog showing the consent categories
Categories, services and declared cookies are presented with data and actions from the central engine.
Evidence & operation

Server-side logging of decisions

Every consent and every later change creates a record on the server alongside the state in the browser. This logging is a fixed part of the process, not an option.

Where the record goes is again decided by the implementation of the interface: by default, the application stores it as a file on its own server. It can just as well pass it via an API to another service that manages it, for example in a database.

What is recorded includes
  • consent ID
  • configuration version
  • the selection made
  • timestamp
  • user agent
  • truncated IP address

IPv4 addresses are truncated after the second block, IPv6 addresses after the third segment. Incoming entries are checked; incomplete or invalid requests are rejected.

Logging supports the traceability of decisions, but it is not audit-proof archiving.

A logging failure does not block the application

The visitor's decision takes effect in the application's consent state first. If the server-side storage fails, the website remains usable.

The error is logged server-side instead of exposing technical details in the browser. The consent system's ability to function therefore does not depend on the logging being available at every moment.

From click to log entry

consent-flow demo
01 Consent settings loaded02 Selection received03 Consent state updated04 Decision recordedProcess completed
Schematic representation – not output from the actual system logs.
  1. 01

    Choice in the banner

    The visitor decides per category which services to allow. Essential storage values remain active.

  2. 02

    Applied in the application

    The engine stores the selection, updates Google Consent Mode and enables the allowed services.

  3. 03

    Logged on the server

    The decision is logged with version and timestamp.

Where it fits

Why building it ourselves was the obvious choice

The goal was to keep dependencies and ongoing costs from arising in the first place. That we could achieve this quickly and reliably came down to what we already brought with us.

Expertise in data protection and consent
How consent, Google Consent Mode and the duty to inform visitors fit together is part of our everyday work on web applications.
Our own applications, not a site builder
Our projects are standalone web applications. Consent could therefore be built as part of the application instead of being plugged in from outside.
Our own infrastructure
We run hosting, deployment and the firewall ourselves. Keeping logs on our own servers therefore needed no new service, just one more endpoint in the existing application.
Shared modules
Our projects already share other modules through our private package registry. The consent engine is one of them and is available to every new project.

The consent engine was therefore not a major undertaking but an extension of what was already in place.

Consent can be integrated directly into the application

The central consent state is available to application code as well.

A component can therefore check, for example
  • Is analytics released?
  • May an embedded video be loaded?
  • Does consent need to be obtained before an external map?
  • Is the stored decision still valid for the current consent version?

Consent is therefore not limited to banner and settings dialog but can be integrated directly into the flow of an application.

Full control means full responsibility

Without a provider, there is also nobody who updates cookie lists, adopts changes to Google Consent Mode or adapts texts to new legislation. This work lies with us – as part of the maintenance we provide for our applications anyway – or with the client, when texts and details are maintained through a connected CMS.

Result

Our own foundation for consent, with no vendor in between

Today the consent engine is used in different web applications – with no external vendor, no recurring licence, and with consents and logs on our own infrastructure. Core functions are maintained once, while data, integrations, languages and interface remain project-specific.

Independence
No vendor, no licence, no third-party script in the load path.
Data sovereignty
Configuration, consents and logs live on our own infrastructure.
Consent before consent-dependent services
The corresponding integrations load only after the required consent.
Versioned decisions
Stored consent is bound to the respective state of the consent configuration.
Central consent logic
State, versioning, registry, script gating and withdrawal are managed together.
Reusable and flexible
Data sources, languages and interfaces per project; improvements to the engine via versioned updates.