Skip to content

Latest commit

 

History

89 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

credential-badges

Turn an on-chain Andamio credential into a badge you can see, embed, and share.

A credential badge is the visible face of an Andamio credential: a self-contained SVG that renders a learner's on-chain achievement as something a person can look at, hold, and post anywhere. It is free and open source, and that is the point. Anyone can look at a real badge, understand what an Andamio credential is, and start building with it.

Live on Cardano mainnet. Any credential resolves on demand at:

https://credentials.andamio.io/badges/<policy_id>.<slt_hash>.svg

Look at a real one →

The badge is not just a picture. Its two rings encode the credential's on-chain identity (outer ring = the course policy id, inner ring = the SLT credential hash), so the geometry round-trips back to the chain. The art is the proof. Run make verify to decode a badge and check it against its on-chain hashes.


For developers, start here

Welcome. The fast path in:

You want to... Go to
See a live badge the link above, or any credentials.andamio.io/badges/<policy_id>.<slt_hash>.svg
Map the repo (one line per component) MOC.md
Regenerate the badges locally (offline, Python 3 only) make badges
Set up and contribute CONTRIBUTING.md
See where this is going ROADMAP.md
Understand the deploy model DEPLOY.md

The one rule to know first: badges are build output, not hand-authored files. "If it can be generated, it must be generated." Each SVG is rendered deterministically from on-chain data by the generator in generator/. Never hand-edit a file in badges/. Change the generator (or the source data) and regenerate.

What's served

Four things live at https://credentials.andamio.io:

Path What it is
/badges/<policy_id>.<slt_hash>.svg The badge imagery. Static-first, with an on-demand render fallback, so any credential resolves without being pre-generated. Referenced by achievement.image in the OB 3.0 credential. Presentation-layer only, never identity-bearing.
/context/v1.jsonld The JSON-LD context for Andamio's Open Badges 3.0 extension terms (AttestationHost, OnChainCredentialAnchor, onChainAnchor, onChainAttestation, accessToken, requires, prereqAttestation, courseOwner, flat evidence terms). The current signing context; byte-frozen once published. /context/v0.jsonld is retired but serves forever (credentials reference a version URL for life).
/issuer The hosted OB 3.0 issuer Profile, typed ["Profile","AttestationHost"]. Its id is the DID did:web:credentials.andamio.io (url stays the homepage). Strict verifiers dereference issuer.url here and expect application/ld+json; AttestationHost is defined in /context/v1.jsonld.
/.well-known/did.json The did:web:credentials.andamio.io DID document — publishes the issuer signing key. Verifiers resolve the issuer's did:web here. Served as application/did+ld+json. #key-2026-07 is the active signing key: every committed OB 3.0 credential resolves its proof.verificationMethod to it.

On naming: the badge filename's first half is the credential's course-NFT minting policy id (56-hex). In Andamio a course is identified by its course-NFT minting policy, so that policy id is the course identifier, not a separate one. The second half is the SLT (credential) hash. The full convention and its invariants — including the name is frozen, the picture is not — are in docs/badge-registry.md.

How a badge resolves

Static-first, with an on-demand render fallback, so nothing has to be pre-generated:

  1. Static hit. If the SVG is in the pre-generated set baked into the static host, nginx serves it from disk.
  2. Miss → render. A /badges/ miss returns nginx 404 → @render, which proxies to a second Cloud Run service (credential-badges-render).
  3. Render + cache. The render service reads the course and module titles from the Andamio API gateway, renders the SVG, and caches it in GCS. Repeat requests serve from cache.

Titles are the only thing fetched. The badge geometry is the proof-ring encoding of the on-chain credential, so the art is reproducible offline (make badges).


What's built

✅ Built: v1.0 (mainnet core), shipped 2026-06-29

A learner's on-chain credential renders as a badge that is visible in the Andamio app and resolves on demand for any credential, live on Cardano mainnet.

  • Static host live at credentials.andamio.io (context, issuer profile, badges).
  • Real badge imagery for live credentials, keyed <policy_id>.<slt_hash>.
  • On-demand generation: any credential, including newly issued ones, renders through the public host (static-first, nginx 404 → @render to the render service, GCS-cached).
  • Badges shown in the Andamio app on the learner's Credentials page.
  • Proof-Ring encoding verified to round-trip to on-chain hashes (make verify).

✅ Built: v1.1 (the portable / verifiable layer), shipped 2026-07-23

The badge is now an independently verifiable OB 3.0 / Verifiable Credential that travels off-platform, not just a Proof-Ring plus an on-chain anchor.

  • Ed25519 signing through GCP KMS, anchor-gated: nothing is signed unless a live on-chain check passes first.
  • OB 3.0 signed-VC baking — all 58 rendered badges carry a signed Class Achievement, validated 13/13 against the 1EdTech reference validator.
  • did:web:credentials.andamio.io issuer identity, with a hosted how-to-check page that walks the verification path without trusting Andamio.
  • A signed key-epoch BitstringStatusList for suspension signalling — the key-compromise kill-switch.
  • A third-party embed (@andamio/andamio-badge web component) and a per-holder viewer.

A badge's proof is now its signature and its Proof-Ring encoding and its on-chain anchor.

Not built: the per-holder half of baking. A baked badge carries the holder-free Class Achievement — what the badge means — not a per-holder credential. That is deliberate: holder identity in public git history is permanent and un-purgeable, so per-holder artifacts are served on demand rather than committed. See ROADMAP.md and #89.

Two version axes, do not conflate them. The repo/release tag (v1.0.0, which deploys the static host) is separate from the JSON-LD schema version. v1.jsonld shipped 2026-07-23 as a byte-copy of the (mutated) v0 at a fresh URL — a cache-migration bump, not a vocabulary change (see docs/solutions/conventions/never-mutate-published-jsonld-context.md). Vocabulary changes ship as new version files (v2.jsonld, ...). Tagging the repo does not version the schema.


Ongoing work (live checklist)

The authoritative, phase-by-phase checklist lives in ROADMAP.md (tick boxes as items close). Snapshot of what's live now and what's moving next:

  • v1.0 mainnet core: render + serve any credential on demand (shipped 2026-06-29)
  • Badges shown in the Andamio app (Credentials page)
  • "Look at this badge" in the app (in progress, andamio-app-v2): show earnable badges on the public course page, the badge in the module learning UX, and an enlarge + metadata + shareable-link path on the Credentials page (app-v2 #738)
  • v1.1 Phase 0: evidence gate (external verifier runs + comprehension cohort) (#15#21)
  • v1.1 Phase 1: Ed25519 sign key + did.json CI emission
  • v1.1 Phase 2–3: signed-credential service + human verification page

Known issues and good entry points are in GitHub Issues. Look for good first issue and documentation.


How you can use this

Some things you can build on today, and where it's headed:

  • Embed a learner's badge anywhere. It is a plain SVG at a stable URL, no API key needed to read:
    <img src="https://credentials.andamio.io/badges/<policy_id>.<slt_hash>.svg"
         alt="Andamio credential badge" />
  • Resolve any credential on demand. You do not need a badge to be pre-generated. Request the URL for any (policy_id, slt_hash) pair and the host renders and caches it on first hit.
  • Verify a badge against the chain. The rings are an encoding, not decoration. make verify decodes a built badge and confirms it matches its on-chain hashes, so the image is self-checking.
  • Read the credential's schema. Fetch /context/v1.jsonld to see Andamio's OB 3.0 extension terms and build your own renderer or validator against them.
  • Regenerate or restyle locally. make badges renders the full set offline and deterministically. Fork the generator in generator/ to experiment with palettes or encodings (gen.py, colors.py).
  • Embed a badge as a web component. @andamio/andamio-badge is published to npm — drop <andamio-badge> into your own app and it renders from the public host, no Andamio account required.
  • Extract and verify the signed credential yourself. Every rendered badge carries a signed OB 3.0 Class Achievement baked into the SVG. Pull it out, resolve did:web:credentials.andamio.io, and check the signature with any Data Integrity verifier — the how-to-check page walks the whole path without trusting us.

If you build something with these, or want a surface that does not exist yet, open an issue. We want this to be a thing people pick up and run with.


Contributing

Credential badges are free and open source, and contributions are welcome. Start with CONTRIBUTING.md for the setup, the build-output rule, and how changes ship (tag-triggered deploy, served-file allowlist). New contributors: the good first issue and documentation labels are the best entry points, and ROADMAP.md shows what's next. Participation is covered by our Code of Conduct.

Background

These extension terms came out of the Andamio Open Badges 3.0 spike (April–May 2026). That prototype is committed at archive/ as history; the production signing path it became lives at signing/. The full deployment plan that promotes it lives at docs/plans/2026-05-16-001-feat-andamio-ob3-issuer-deployment-plan.md.

License

Apache License 2.0 © Andamio Platform.

About

No description, website, or topics provided.

Resources

Code of conduct

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages