Security and privacy
Certichain's promise is that anyone can check a credential is genuine, issued by a registered institution and not cancelled, while personal data stays with the holder. This section explains how the design keeps that promise, which parties and components it has to trust, how keys are handled, and what is still open.
Certichain runs on the Ethereum Sepolia test network with synthetic data. It has not had an external smart contract audit, an external zero-knowledge audit or the independent cryptography review planned in the roadmap. Do not use it for real credentials or real personal data.
Pages in this section
| Page | What it covers |
|---|---|
| Threat model | Assets, actors and trust boundaries; the threats considered and how each is handled; what remains. |
| Privacy design | What is on chain, on the server, in the pinning service and with the holder; why; the data protection impact assessment status. |
| Key management | Every key and secret the system uses, by name: who holds it, what it can do, how it is derived or rotated. |
| Known limits | Limits and open items as of 2026-10-24, grouped by area. |
Security principles
- The chain is the source of truth. Issuer registration, credential anchors, signatures and status are read from contracts. A verifier needs no account, and no Certichain server decides the answer: the verify page reads the chain through a public RPC endpoint, and the script
blockchain/scripts/verify-credential.tschecks the same signature from a package file. - Secrets stay on the user's device. Hashing, commitments, encryption, key derivation and zero-knowledge proofs run in the browser. The server never receives a plaintext document, a document key, a private key or a student's name.
- Signatures, not trust in transport. A credential is valid because the registered issuer signed it (EIP-712) and the chain accepted it, not because a server says so. Server-signed outputs (verification API answers, status lists) are signed by dedicated keys whose addresses verifiers pin.
- Least power, slowest path for the most power. Issuers manage only their own credentials. A guardian can stop issuance but cannot change who is trusted. The admin is a multisig, admin transfers are delayed, and admin actions on the newer set go through a timelock.
- Nothing deletable on chain. Credentials are suspended, revoked or superseded, never erased, so history cannot be rewritten. No plaintext personal data is written to the v0.3 contracts, which is what makes this permanence acceptable.
- Validate every boundary. Every file a user loads (package, grant, disclosure, VC, invitation, import file) is parsed strictly, with unknown fields refused. Every server route checks size, type, session and rate limits before work.
Reporting a vulnerability
The repository's SECURITY.md is the public policy. In short:
- Report privately through GitHub: the repository's Security tab, Report a vulnerability. Do not open a public issue.
- Targets: acknowledgement within 5 working days, a first assessment within 15 working days, updates at least every 30 days, coordinated disclosure after a fix or 90 days.
- Scope: the contracts, the web application and its API routes, the verification API, the JavaScript SDK and the files they produce. Third-party services, social engineering and volume denial of service are out of scope.
- Rewards are not open yet; they open after the external audit fixes are released.
The handbook notes that GitHub private vulnerability reporting must be switched on in the repository settings by the owner.
Related pages
- Trust boundaries
- Security controls (server routes)
- Access control and governance
- Encryption
Source files
SECURITY.mdsrc/lib/security-headers.ts,src/lib/server/limits.ts,src/lib/server/issuer-session.tsblockchain/contracts/v03/,blockchain/contracts/zk/CertichainAccessGate.sol