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).

BadgeURL
A certificatehttps://brunel.cloud/api/badge/<certificate-id>
The latest published certificate of a repositoryhttps://brunel.cloud/api/badge/github/<owner>/<repo>
Round medal styleadd ?style=medal to either URL
README.md
[![Brunel certificate](https://brunel.cloud/api/badge/github/acme/shop)](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

PathContent
/verify/<id>Status, facts, criteria and evidence, badge snippets, offline verification steps
/verify/<id>/certificatePrintable certificate (save as PDF)
/api/certificates/<id>/credentialThe signed credential (compact JWS)
/api/certificates/<id>/verifyVerification result as JSON
/api/certificates/revocationsRevocation list: ids, dates, reasons
/.well-known/jwks.jsonIssuer public keys (JWK Set)
/.well-known/did.jsonIssuer did:web document
/company/<slug>, /rankingCompany profiles and the ranking

The credential

An Open Badges 3.0 OpenBadgeCredential (W3C Verifiable Credentials 2.0 data model), signed as a compact JWS:

HeaderValue
algEdDSA (Ed25519)
typvc+jwt
kidRFC 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

  1. Download the credential from /api/certificates/<id>/credential, split the JWS and read the header's kid.
  2. Take the key with that kid from https://brunel.cloud/.well-known/jwks.json and verify the Ed25519 signature over header.payload with any JOSE library.
  3. Check that the payload names the repository and commit you expect, that exp is in the future, and that the id is not in the revocation list.
verify.ts (jose)
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.

Badges and verification · Brunel Docs