Skip to content

NewThe DPDP Rules phase in by May 2027.Check your website’s consent readiness

Home

Blog

Consent you can prove: how signed receipts work

Why a log entry is not proof, and how hash chains, signatures and daily anchors make consent records checkable by anyone.

Arjun Raj7 min readDraft

Most consent tools keep a log: a table with a timestamp, a user, and the boxes they ticked. When someone asks "did this person agree?", you open the table and point at the row.

That row tells you what the database says today. It does not tell you what the person actually chose. Anyone with write access, which includes the vendor, a careless script and a well-meaning admin, can change it, and nothing about the row would look different afterwards. A log is a record. It is not proof.

This post explains how OptProof turns each consent into something closer to proof, using three ordinary pieces of cryptography, and where the limits are.

What "proof" needs to mean#

When a business, an auditor or the Data Protection Board looks at a consent record, they want to know three things:

  1. Is this record genuine? Did it come from the consent system, or was it typed in later?
  2. Has it changed? Is it the same today as on the day it was written?
  3. Is anything missing? Were later records, such as a withdrawal, quietly removed?

A plain database row cannot answer any of these on its own. The answer has to come from something outside the row.

Step one: chain the records together#

Every consent decision in OptProof is stored as an event: grant, deny, withdraw or expire, with the purposes, the notice version, the channel and the time. Events for one website, app or clinic location form a single sequence, numbered 1, 2, 3 and so on with no gaps.

Each event's hash is computed from the previous event's hash plus the event's own contents:

text
hash(event 42) = SHA-256( hash(event 41) + contents of event 42 )

A hash is a short fingerprint of some data. Change one character of the input and the fingerprint changes completely. Because every hash includes the one before it, the chain behaves like a row of dominoes:

  • Edit an old event, and its hash no longer matches.
  • Recompute that hash to hide the edit, and the next event no longer links to it.
  • Delete an event, and there is a gap in the numbers and a broken link.
  • Reorder events, and the links break the same way.

This makes the ledger tamper-evident. It does not stop someone with database access from changing history. It makes the change detectable by anyone who checks.

Step two: sign a receipt for every event#

A chain only helps if someone outside the database knows what the chain looked like. So for every event, OptProof issues a receipt signed with an Ed25519 key.

The receipt is a short signed token. It contains a receipt code like OP-7K2M-9QXD, the event's position in the chain, its hash, the action, the purposes, the notice version, the language, the channel and the time. It deliberately contains no personal data: no phone number, no email, no name.

The person can keep it. The widget offers it straight after they choose; the preference centre lists every receipt they have; a PDF version carries a QR code.

The signature means two things. Nobody can make up a receipt without OptProof's private key. And nobody, including OptProof, can change a receipt someone already holds without the signature failing. Once a person has a receipt for event 42 with a particular hash, the ledger has to keep producing that same hash for event 42, or the mismatch shows.

Public keys are published, including retired ones, so a receipt signed years ago still checks out after the key is rotated.

Step three: anchor the chain every day#

Receipts protect the events that people kept receipts for. To protect the whole chain, OptProof also writes a daily anchor.

Shortly after midnight IST, for each property with new events, OptProof signs a small statement: "on this date, the last event was number N and its hash was H". That statement goes into a storage bucket with write-once locking in compliance mode. Objects stored that way cannot be overwritten or deleted by anyone, including us, until the retention period ends.

Because H depends on every event before it, one anchor fixes the entire history of that property up to event N. Rewriting anything earlier would need a new anchor, and the old one cannot be removed.

Checking a receipt#

Anyone can paste a receipt code into verify.optproof.in, with no login. The page runs the checks in the browser:

  • Signature. Is the receipt signed by a published OptProof key?
  • Match. Does it match the stored event, field by field?
  • Chain. Do the hashes recompute correctly from that event to the next anchor, with no gaps?
  • Anchor. Is the anchor genuine, and does it cover this event?

The result is shown in plain language: verified, pending, or failed, with the reason. The full method is published as a specification with test vectors, so an auditor or a developer can write their own verifier and not rely on ours at all.

What this does not prove#

Being honest about the limits matters as much as the mechanism.

  • The first day. Until an event is covered by a daily anchor, which can take up to about a day, the only protection against a rewrite is the receipt already given to the person. The verifier shows this state as pending, not verified.
  • One family of keys. Receipts and anchors are both signed with OptProof keys. In principle, someone holding a current private key could sign a new anchor for a rewritten history. What stops a silent rewrite is that older anchors sit in write-once storage, that receipts already issued bind each event's hash, and, in a later phase, that daily anchors will also be published on a public feed so others can keep their own copies. An auditor who keeps their own copies gets the strongest assurance.
  • Who the person was. A receipt shows that OptProof recorded a particular decision at a particular time. It does not prove the identity of the person beyond a pseudonymous reference.
  • Whether the consent was valid in law. Verification shows the record is authentic and unchanged. It does not judge whether the notice was clear or the consent met the legal standard. That is still the business's job.

A withdrawal does not erase a receipt#

People sometimes ask what happens to the receipt when someone later withdraws. The receipt stays valid, because it is an accurate record of what happened at that moment. The withdrawal is a new event with its own receipt. The verifier tells you when a receipt has been superseded, so nobody mistakes an old grant for a current one.

Why this matters for a small business#

None of this asks the business to understand cryptography. The point is the conversation it makes possible. When a customer says "I never agreed to that", the answer is not "our database says you did". It is "here is the receipt you were given at the time; you can check it yourself".

That is a different kind of answer, and it is what we mean by consent you can prove.

Where to go next