# LocalCMP: what a local-first consent architecture actually changes

Ben Morin, 2026-08-07. https://bemorin.com/writing/localcmp-local-first-consent-infrastructure

> Cookie banners are usually treated as interface components. LocalCMP explores a different boundary: keep the user’s signed choice in the browser, publish the policy mechanism openly, and make the consent path testable.

Most consent products are presented as banners.

That framing hides the harder part: **what mechanism actually records a choice, applies it, proves what was configured, and lets somebody audit the result later?**

LocalCMP is a prototype around that systems question.

Project page: [LocalCMP](/work/localcmp).

Its current architecture is local-first: the browser keeps the signed choice while the site publishes the mechanism used to interpret and apply that choice.

## The core idea

The system currently combines:

- default refusal and consent by purpose;
- a locally stored receipt signed with ES256;
- a versioned public manifest;
- a privacy centre and withdrawal flow;
- an initial HTML scanner;
- a Chromium scanner that can observe before consent, after refusal, and after authorization;
- deterministic checks for legal pages;
- optional local AI review through Ollama;
- a guided configuration studio;
- a searchable knowledge base.

The important part is not the banner styling. It is the separation between **choice**, **policy**, **execution**, and **auditability**.

## Why keep the receipt local?

A consent event is often treated as something that immediately belongs in a remote vendor database.

LocalCMP tests a different default: keep the signed receipt in the browser and make remote collection a separate product decision rather than an architectural requirement.

That changes the trust model.

The user’s browser can hold the evidence of the current choice while the website exposes a versioned manifest describing purposes, vendors, durations, and behavior.

The benefit is not that "local" magically equals compliant. The benefit is that the boundary becomes easier to reason about.

## A public manifest makes configuration inspectable

Consent systems are difficult to audit when the interface says one thing and the runtime does another.

A versioned public manifest can become the contract between configuration and execution.

That gives several useful properties:

1. the current policy can be inspected without opening an admin dashboard;
2. a deployment can be associated with a specific configuration version;
3. automated scanners can compare observed network behavior with declared intent;
4. changes can be reviewed as configuration changes rather than invisible dashboard edits.

The prototype includes a public `.well-known` manifest for this reason.

## Scan the behavior, not only the markup

A banner can look perfect while trackers still fire before a choice is made.

LocalCMP therefore distinguishes between a simple HTML scan and a Chromium-based runtime scan.

The runtime scanner is designed around three states:

- before a choice;
- after refusal;
- after authorization.

That makes the audit question much more concrete: **what network behavior changed after each state transition?**

A deterministic scanner is also more useful than asking an LLM whether a page "looks compliant". Local AI can help review wording or surface suspicious patterns, but it should not replace observable checks.

## Signed receipts are not a compliance shortcut

The prototype signs local receipts with ES256.

That can help establish integrity: a stored choice can carry cryptographic evidence that it was produced by the expected mechanism.

But cryptography does not decide whether the policy itself is lawful.

The project explicitly separates technical integrity from legal guarantees. Texts, purposes, providers, retention periods, legal bases, languages, rights contacts, and deployment details still have to be configured correctly.

## What LocalCMP does not claim

This is where the architecture becomes more credible.

The current project does **not** claim:

- public IAB TCF validation;
- Google CMP certification for publisher environments that require it;
- a finalized Microsoft UET bridge;
- automatic compliance with every law and territory.

That matters because a technically interesting consent engine is not automatically a drop-in replacement in every advertising environment.

For publishers that require Google-certified CMP or IAB programs, those external program requirements remain real constraints.

## Why I built it this way

The broader thesis is that privacy tooling should be easier to inspect.

A useful consent system should answer questions such as:

- What did the user choose?
- Which policy version was active?
- What scripts ran before the choice?
- What changed after refusal?
- What changed after consent?
- Can the mechanism be tested without trusting the vendor dashboard?
- Can the implementation clearly state where it is not suitable?

That is more interesting to me than another banner configurator.

LocalCMP is therefore less a visual component than an experiment in **consent infrastructure as an observable protocol**.
