Consent ledger & §6(10) receipts
Every consent decision is appended to a per-tenant, append-only hash chain. Each record links to the previous one by hash, and the head is signed — so any tampering (editing a purpose, back-dating, deleting a link) breaks verification. This is what makes a NoIdMe consent a §6(10) receipt: not a log entry, but evidence.
What's in a record
- Who & what — principal, purposes, the lawful basis (consent / §7 legitimate use / §17 exemption — never collapsed to "consent").
- Against which notice — the exact notice version + hash + language the decision was made against.
- Provenance — affirmative action, age band + assurance, and (for children) the parental-consent proof.
- Chain — sequence number, this record's hash, the previous hash, and a signature.
Signing modes
The chain is signed per tenant. Three modes, by DPDP_SIGNER:
- hmac (dev) — tamper-evident but repudiable.
- ecdsa — asymmetric P-256; verifiable with the public half (non-repudiation), but in-process keys are volatile.
- kms — a KMS-delegated per-tenant key (the private half never enters the process); non-repudiation that survives restarts. This is the production path.
Anyone can verify
Because the public key is published (JWKS), a third party can verify a chain without any secret:
curl -X POST https://api.noidme.com/v1/verify \
-d '{"records":[ ...the principal's records... ]}'
# → { "valid": true, "authenticityChecked": true, "kid": "…" }