Size, MIME, and magic-byte verified before any byte is stored; SHA-256 over the stored bytes; a QR certificate anyone can verify offline.
Upload gate to certificate — end to end
Four gates before a single byte is stored. Size, MIME allow-list, magic-byte header, and rate-limit all run before the Supabase write — a spoofed Content-Type or renamed polyglot is rejected 422, never persisted.
The hash proves the stored bytes. SHA-256 is computed over the exact bytes written to storage and recorded against the claimant — so the certificate certifies what is actually on disk, bound to a KYC identity.
Verifiable offline. The certificate carries a structured CERT-YYYY-ENTITY id and a compact QR value; a verifier re-hashes the bytes and confirms authenticity without ever calling the server.
Mail = email sent Bell = in-app alert Amber diamond = automatic check
No byte reaches storage until size, MIME allow-list, and the magic-byte header all pass — a renamed file is caught at the door. The SHA-256 is taken over the STORED bytes, so the certificate proves exactly what is on disk; the QR makes that proof verifiable offline.
What the certificate guarantees
The magic-byte gate is the anti-spoof wall — declared image/png must actually start with the PNG signature, or it is a 422.
The stored path is workspace-scoped and sanitised; the SHA-256 + path land in an uploads record bound to uploaded_by.
The QR value is self-contained — entity id, cert id, and hash prefix — so verification is a re-hash, not a lookup.