Privacy design
A public blockchain is permanent and readable by everyone, which is the opposite of what personal data needs. Certichain resolves this by putting only fingerprints on chain and keeping the data itself with the holder. This page shows where every piece of data lives, what each party can learn, and what is still open.
Where data lives
| Data | Where | Who can read it | Why it is there |
|---|---|---|---|
| Issuer address, registered name, roles | Chain | Everyone | Verifiers must know who is a registered institution |
Credential anchor: issuer, subjectCommitment, documentHash, metadataHash, record type, dates | Chain | Everyone | What a verifier checks against |
| Issuer's EIP-712 signature | Chain, in the CredentialSigned event | Everyone | Lets anyone re-check the signature |
| Status history: status, reason code, note hash, who changed it | Chain | Everyone | Cancellation must be public; reasons are coarse codes and notes are hashed |
| Holder binding: enrolment commitment to wallet address | Chain | Everyone | Lets the holder's wallet prove ownership and receive an inbox |
| Custom record type names and descriptions | Chain | Everyone | Verifiers see what kind of credential it is |
| Access group commitments and receipts (with the sender's address) | Chain | Everyone | Anonymous proof of admitted access |
Holder details (holderName, studentId, programme, award, awardedOn) | Credential package | The holder, and whoever they share it with | Needed to open the commitments |
| Subject salt, metadata salt, disclosure salts | Credential package | Same | Needed to open the commitments and disclosure tree |
| Document key and CID | Credential package; grant files (wrapped); capability links | Same | Needed to fetch and decrypt the document |
| Encrypted document container | IPFS, pinned by Pinata, labelled with document hash and issuer | Anyone with the CID can fetch the ciphertext | Off-chain storage the issuer does not have to run |
| Sign-in nonces, rate-limit counters, monitor history | Redis (Upstash) | The operator | Server security and operations |
| Session | A signed cookie in the issuer's browser | The issuer's browser and the server | Upload authorisation |
The server keeps no application database of credentials or students. Lists in the app are rebuilt from chain events in the user's browser.
Why fingerprints are safe to publish
- Salted commitments (see Hashing and commitments) hide names and student ids even from someone who has a list of candidates, because the 32-byte salt is unknown to them.
- The metadata salt is fresh for every credential, so one package cannot be used to test guesses against another credential.
- The document hash reveals nothing about the document. It does let someone who already holds a candidate file confirm it was issued, which is its purpose.
- A test scans the v0.3 contracts and their ABI for plaintext personal fields (
blockchain/test/v03/NoPlaintext.test.ts).
The v0.2 AcademicRecords contract (release v2.0.0) stores the student id, student name, student wallet address and the IPFS hash of a plaintext document on chain (the Record struct in blockchain/contracts/interfaces/IAcademicRecords.sol). It is still deployed on Sepolia and the app still supports it when NEXT_PUBLIC_CONTRACT_VERSION is not v03. Only synthetic data may be used with it. See Legacy v0.2.
What each party can learn
| Party | Learns | Does not learn |
|---|---|---|
| Anyone reading the chain | Which institutions issued how many credentials of which types, when, and their status history; which wallets are bound to some enrolment of an issuer | Names, student ids, documents, which person a commitment belongs to |
| The pinning service and gateways | That an issuer stored a container of a certain padded size for a document hash | The document, the holder |
| The Certichain server | Which issuer wallet uploaded what ciphertext and when; request metadata such as IP addresses for rate limiting | Plaintext documents, keys, holder details |
| An RPC provider | Which credential ids a browser looks up, and from which IP address | Holder details |
| A verifier given a package or VC | All holder details in it | Fields left out of a selective disclosure |
| A verifier given a selective disclosure | Only the chosen fields, proven against the issuer's signature | The other fields, or whether an absent field exists |
| A status list reader | The bit for the credential they check; a list covers one issuer | Nothing is sent to the publisher about which bit was read |
| An observer of access receipts | That some admitted identity proved access to a credential on a day, and the sending address | Which admitted identity it was |
Holder control
The design lets the holder decide what to share:
- The package reveals everything; it should be shared only with parties that need all details.
- A VC or Open Badge export includes the holder details and salts when the package has them, so it is as revealing as the package for those fields. It never includes the document key, CID or disclosure data.
- A selective disclosure reveals only chosen fields, bound to one verifier's challenge (see Selective disclosure).
- A grant file gives one recipient the document without any holder details.
- A capability link gives anyone with the link the document; it should be treated like the document itself.
- The phone wallet makes a QR code that carries the holder's details only when the holder chooses to add them (
src/app/wallet/CredentialCard.tsx).
Erasure and the right to be forgotten
Nothing written to a public chain can be deleted. Certichain therefore writes nothing to the v0.3 contracts that identifies a person without the off-chain salt. In practice:
- A credential can be revoked, so it no longer verifies, but its anchor remains.
- The issuer can unpin containers; copies cached by other IPFS nodes may survive for a while, as ciphertext.
- If the holder destroys every copy of the package, the commitments on chain can no longer be linked to them by anyone without the salts. The issuer can re-derive the stable student salt with its wallet, so the issuer can still link an enrolled student's commitments.
Data protection impact assessment
A DPIA (data protection impact assessment) is the formal record of how a system processes personal data, the risks and the mitigations. An engineering draft exists in the handbook at docs/compliance/DPIA.md, written on 2026-10-12. As of 2026-10-24 its status is draft for legal review: the legal review has been requested from the project owner and is not done (open question Q-19 in the handbook). The draft is an engineering assessment, not legal advice, and no production use should rely on it.
Source files
src/lib/commitments.ts,src/lib/credential-package.ts,src/lib/disclosure/src/lib/vc/export.ts,src/lib/vc/openbadges/src/app/api/upload/route.ts,src/lib/server/pinata.tssrc/lib/server/rate-limit.ts,src/lib/server/session.tssrc/app/wallet/CredentialCard.tsx,src/lib/present/static-code.tsblockchain/contracts/v03/,blockchain/contracts/interfaces/IAcademicRecords.soldocs/compliance/DPIA.md(handbook)
Tests
blockchain/test/v03/NoPlaintext.test.tssrc/app/data-exposure.test.tssrc/lib/commitments.test.ts,src/lib/credential-disclosure.test.ts,src/lib/disclosure/disclosure.test.tssrc/lib/vc/export.test.ts