Verify a certificate
Paste the link or the identifier printed on the certificate, or scan its code. This page fetches the signed token and the published key set and verifies the signature in your browser — it does not ask us whether the certificate is good.
The camera picture stays on your device. Nothing is uploaded.
Your phone's camera can open the code too. Scanning here adds one check: it refuses any code that does not point to purposesource.org.
Check the holder's certificate against this record
This record publishes the certificate's status and its token's hash, and no name and no signed token. The holder proves the certificate is theirs by showing the signed file to whoever they choose. Paste the token you were shown: it is checked here against this record's hash, the published keys and the transparency log, and sent nowhere.
Is this yours? Manage it in your dashboard.
Check the signed original:
How to check a copy
- Paper or a picture (a PDF, a certificate picture or a share card): scan its code or type its certificate id here, then compare the id, the name, the period and the projects printed on it with what this page shows. A copy shows what was true when it was made; this page shows the status now.
- A QR code should open purposesource.org/verify/ followed by the certificate id, optionally followed by #h= and a fingerprint, and no other address. The scanner on this page refuses a code that points anywhere else.
- A badge should link to this page, at purposesource.org/verify, with the same certificate id.
- The signed file (certificate.jws): paste its token into the box below. Your browser checks its signature against the published key.
- A status-only record shows no name, so a name on a copy cannot be checked here: ask the holder for the signed file.
The fingerprint shows which signed version of the certificate this copy was made from. Anyone can copy it, so it proves nothing on its own.
Details
What was checked
Signed token
The pattern is drawn from this certificate's hash. It is decoration, not proof.
Offline mode — paste a token
Verify a certificate token against the published key set without looking anything up. Useful when you have the artifact but not the identifier, and for checking that a certificate you were sent matches one you already trust.
Offline mode checks the signature, and that the signing key's published validity window covers the time the token says it was signed. It cannot check transparency-log inclusion or revocation, so a token that passes here still needs a lookup by identifier to be trusted.
Try a sample certificate
One row per certificate this build published. Each link opens this page with the identifier filled in, and the verdict is then computed in your browser from the signature and the transparency log — not read off this table.
Sample certificates published by this preview. Every one is labelled sample; none is a credential.
| Certificate |
|---|
cert_01m395rstn8dbck57dywp1p907 license-status / waiver · SAMPLE — Jordon and Jordon sample |
What the verdicts mean
Every outcome this page can reach, and what each one asserts
| Verdict | What it means |
|---|---|
| Genuine certificate | Signature verified here, hash present in the transparency log, status current. |
| VERIFIED — attests participation in {year} | A participation certificate past its period. It attests participation in that period, and that does not lapse: the published record says expired because the period is over, and expiry is not revocation. |
| WAS VALID for the period shown | A company certificate past its period. It attests what it attested then — expiry is not revocation and is not a defect. |
| Revoked on {date} ({class}) | Withdrawn, with a date and a reason class. Revocation is prospective: the historical window shown stood while it stood. |
| Superseded — a newer certificate replaces this one | Replaced by a later certificate, linked from the verdict. |
| Not verified — do not rely on it | The signature does not verify — altered, or never issued — or it verifies but the hash is absent from the transparency log, which is what the log is for; or the token could not have been signed by the key it names: it names no key, or one the key set does not carry; it is not ES256; it does not say when it was signed; or it dates itself outside that key's published validity window. |
| … — its signing key was later compromised | The verdict before the dash stands, and the key that signed is now published as compromised; the token dates itself before that key's validity window ends. That date is the signer's own statement: the transparency log, and any incident notice for the key, show whether it was issued then. |
| Could not check — the key set does not settle the signing key | The published key set does not state the signing key's status or validity window in a form this page can apply. The signature is not accepted, and nothing is asserted in either direction. |
| Could not check right now · Could not check the public log | Something could not be fetched: the record, the published keys or the log. Nothing is asserted in either direction — this is deliberately not the same answer as "Not verified". |
| Could not check — you seem to be offline | No network answered at all. Nothing is asserted; connect and reload the page. |
| Status record only — this page cannot confirm whose certificate this is | The published record carries the certificate's status and its token's hash, and no name and no token, so a name printed on a copy is not checked here. Nothing is asserted about whose certificate it is until the holder shows the signed file — paste its token into the holder's box that appears with the record, and the page checks it against the hash, then verifies it. |
| Test certificate — not a real certificate | Signed with a sandbox key. Never a production credential, whatever it looks like. |
| No certificate with this ID | No record is published under the identifier. Ids are long and case-sensitive. |
Offline mode — paste a token answers in the verdict matrix's own words (for example
INVALID — signature does not verify, TRANSPARENCY-LOG INCLUSION UNKNOWN
or CANNOT VALIDATE — not a token type this page can date): it checks the signature
and its key's window, and never the log or the status.
Verifying by hand
Nothing here depends on our code. The steps this page performs are the steps you can perform with a shell and any standard token library. Every document is published twice — as a same-origin static copy on this host, and on the edge API once it is live — and the two are byte-identical by construction:
-
Fetch the status record from
/artifacts/certs/{certId}.json(or/v1/verify/{certId}on the API host). -
Fetch the key set from
/artifacts/jwks.json(or/jwks.json) and select the key by itskid. Then check that the key could sign it: the token'siatmust fall inside the key'spsn:validityWindow(notBeforeincluded,notAfterexcluded), whatever itspsn:status. A retired key still verifies what it signed inside its window; a compromised key's window ends where acceptance ends, never after the compromise, and what it signed before then is shown with a warning. - Verify the ES256 signature over the token's
header.payloadbytes. -
Take the SHA-256 of the compact token and look for it in the transparency log segment
the record names, at
/artifacts/ct/{n}.json(or/ct/{n}.json).
Key rotation history and the log's append-only guarantee are documented on keys and the transparency log. What each class of certificate attests, and the exact wording its holder may publish about it, is the certificate policy.
verify only at purposesource.org/verify — any other address offering to verify our certificates is not ours.