-
Notifications
You must be signed in to change notification settings - Fork 0
Spanish University Credential
Spain's university-wallet pilot (SGAD + FNMT-RCM + UC3M/UM/URV) and the DC4EU education rulebook v3.0 describe exactly the stack openvc verifies: FNMT anchors on the Spanish TLv6 trusted list, EBSI TIR accreditation, and SD-JWT VC / VCDM envelopes. This walkthrough verifies a higher-education diploma with openvc alone — the trust decision and the credential — offline.
The runnable version is
examples/11_spanish_university_credential.py.
A verifier answers two questions, and openvc has an API for each:
-
Is the issuer trusted? The university's document-signer certificate must chain to
an FNMT-RCM root that appears on the Spanish Trusted List (ETSI TS 119 612,
TLv6), reached from the EU List of Trusted Lists (LOTL).
openvc.trustlistfetches and XAdES-verifies those lists into a set of X.509 anchors;openvc.x5cvalidates the signer's chain to one of them and binds it to the issuer id. - Is the credential valid? The diploma is an SD-JWT VC signed by that same FNMT-anchored key, with the student's wallet key binding.
In production the anchors come from the trusted list; openvc.trustlist returns them as
plain x509.Certificate objects (see Trust anchors):
from openvc.trustlist import consume_trust_list
anchors = consume_trust_list(
"https://ec.europa.eu/tools/lotl/eu-lotl.xml", territories={"ES"})
fnmt_anchors = anchors.certificates() # FNMT-RCM roots on the ES listThe university's document-signer chain is then validated to those anchors and bound to the
issuer id (the diploma's iss, matched against the certificate SAN), which yields the
issuer's public key:
from openvc.x5c import resolve_x5c_key
issuer_jwk = resolve_x5c_key(x5c_chain, "https://sede.uc3m.es", trust_anchors=fnmt_anchors)The diploma is a DC4EU European Higher-Education Diploma (vct: https://dc4eu.eu/credentials/EUHED), issued by the university's key and bound to the
student's wallet key. It is verified with the FNMT-anchored issuer_jwk from step 1 —
so a diploma only verifies if its signer is trusted on the Spanish list:
from openvc.proof.sd_jwt import SdJwtVcProofSuite
result = SdJwtVcProofSuite().verify(
presentation, public_key_jwk=issuer_jwk,
audience="https://empleador.example", nonce=nonce,
require_key_binding=True, expected_vct="https://dc4eu.eu/credentials/EUHED")
# result.issuer, result.vct, result.key_bound, result.claims["title"], …Selectively-disclosable claims (e.g. final_grade, given_name) let the student reveal
only what an employer needs. Run the example above for the full offline flow.
DC4EU runs over EBSI trust registries too: an issuer holds an accreditation in the
EBSI Trusted Issuers Registry (TIR), recursively anchored to a Root Trusted Accreditation
Organisation. openvc_ebsi.verify_ebsi_badge verifies an EBSI-issued VC-JWT and walks that
accreditation chain (needs the [ebsi] extra and registry access — see
Trust anchors):
from openvc_ebsi.verify import verify_ebsi_badge
badge = verify_ebsi_badge(
token, resolver=ebsi_resolver, proof_suite=vc_jwt_suite,
expected_types=["VerifiableEducationalID"],
trust_anchors={"did:ebsi:zRootTAO…"}) # the recursive chain to a trusted RootTAOThe two anchors are complementary: the FNMT / Spanish trusted list is the eIDAS/national route, and EBSI TIR is the DC4EU/ecosystem route. A verifier can require either or both.
- The runnable example mints an FNMT-analog root offline (no network); swap it for real
openvc.trustlistanchors in production. - SD-JWT VC issuance does not yet emit an
x5cheader, so the walkthrough validates the signer chain (resolve_x5c_key) and verifies the SD-JWT VC with the resulting key as two steps (#94 tracks foldingx5cinto the SD-JWT VC issuer JWT soverify_credential(..., x5c_trust_anchors=…)does both at once).
📖 Published automatically from the wiki/ directory of the main repository — edits made directly on the wiki are overwritten by the next sync. To change a page, open a PR against wiki/. Every python block on these pages is executed by CI. · API reference · LGPL-3.0-or-later
Start
Proof formats
Verifying in practice
- Presentations & OpenID4VP
- Resolving issuer keys
- Relying-party certificates
- Credential schemas
- Status lists
- Trust anchors: EU TL & EBSI
- Async verification
Walkthroughs
Operating
Reference