Certification
Badges and verification
Embed a live certificate badge in a README, link the verification page, and verify a Brunel credential yourself, online or offline, with the issuer's public keys.
Badges
Badges are SVG images with the live status of a certificate (valid, expired or revoked).
| Badge | URL |
|---|---|
| A certificate | https://brunel.cloud/api/badge/<certificate-id> |
| The latest published certificate of a repository | https://brunel.cloud/api/badge/github/<owner>/<repo> |
| Round medal style | add ?style=medal to either URL |
[](https://brunel.cloud/verify/github/acme/shop)https://brunel.cloud/verify/github/<owner>/<repo> always redirects to the latest published certificate of the repository, so the link in your README never goes stale.
Public endpoints
| Path | Content |
|---|---|
/verify/<id> | Status, facts, criteria and evidence, badge snippets, offline verification steps |
/verify/<id>/certificate | Printable certificate (save as PDF) |
/api/certificates/<id>/credential | The signed credential (compact JWS) |
/api/certificates/<id>/verify | Verification result as JSON |
/api/certificates/revocations | Revocation list: ids, dates, reasons |
/.well-known/jwks.json | Issuer public keys (JWK Set) |
/.well-known/did.json | Issuer did:web document |
/company/<slug>, /ranking | Company profiles and the ranking |
The credential
An Open Badges 3.0 OpenBadgeCredential (W3C Verifiable Credentials 2.0 data model), signed as a compact JWS:
| Header | Value |
|---|---|
alg | EdDSA (Ed25519) |
typ | vc+jwt |
kid | RFC 7638 thumbprint of the issuer key |
It binds the certificate id, the repository id and name, the commit, the level, the score, the catalog version and digest, the issue and expiry dates, and the issuer's did:web.
Verify offline
- Download the credential from
/api/certificates/<id>/credential, split the JWS and read the header'skid. - Take the key with that
kidfromhttps://brunel.cloud/.well-known/jwks.jsonand verify the Ed25519 signature overheader.payloadwith any JOSE library. - Check that the payload names the repository and commit you expect, that
expis in the future, and that the id is not in the revocation list.
import { createRemoteJWKSet, jwtVerify } from "jose";
const jwks = createRemoteJWKSet(new URL("https://brunel.cloud/.well-known/jwks.json"));
const jws = await (await fetch(`https://brunel.cloud/api/certificates/${id}/credential`)).text();
const { payload, protectedHeader } = await jwtVerify(jws, jwks, { algorithms: ["EdDSA"] });
console.log(protectedHeader.kid, payload);Key rotation
During a rotation, the previous key stays published for verification only and is never used to sign. If a key were ever compromised, it would be removed at once: its certificates would no longer verify and would be listed as revoked with the reason key_compromised.