Verifiable Credentials integration - Solution Notes
Status
The implementation of the Verifiable Credentials integration is in progress as part of [CLOSED] FC-0006 - Credentials Implementation.
Comments and questions about Verifiable Credentials are welcome.
Related Epic in credentials roadmap: https://github.com/openedx/credentials/issues/1731
ADRs: https://github.com/openedx/credentials/pull/1846
Open questions
TL;DR
This work will extend the Open edX Credentials service to allow the sharing of verifiable credentials to external networks. The extension is proposed to be a new Django application in the Credentials service and to be general purpose so as to allow sharing to arbitrary networks in the future.
The focus for the first increment will be the OpenBadges v3 protocol, which is hot off the presses, but is where a lot of energy across W3C, 1EdTech seems to be converging. The first increment will target sharing the the DCC wallet mobile application developed by the Digital Credentials Consortium at MIT.
Table of Contents
- 1 Status
- 2 Open questions
- 3 TL;DR
- 4 Table of Contents
- 5 Intro: Verifiable credentials scheme for education
- 5.1 Terminology
- 6 Existing Implementations
- 7 Design Proposal
- 7.1 High-Level design
- 7.2 Implementation details
- 7.2.1 Issuer configuration (including specifying the private keys and credentials)
- 7.2.2 Django admin configuration
- 7.2.3 Issuing VC
- 7.2.4 Issue a credential to DC learner wallet sequence diagram
- 7.2.5 MFE wireframes
- 7.2.6 Signing Credential
- 7.2.7 Adding credentials to a digital wallet
- 7.2.8 Forming verifiable credentials or digital credentials using the learners' data
- 7.2.9 Invalidating VC (changing status)
- 7.2.10 Issuing digital credentials (badges)
- 8 Future possible enhancements
- 9 Rejected alternatives
Intro: Verifiable credentials scheme for education
In the document Intro to Verifiable Credentials you will find a description of verifiable credentials concepts, lifecycle, and useful links to vc specifications.
Terminology
VC — Verifiable Credential, according to vc data model (https://www.w3.org/TR/vc-data-model/)
Credential — A set of one or more claims made by an issuer about a subject.
DCC — Digital Credentials Consortium https://digitalcredentials.mit.edu/
Digital Credentials Wallet — Digital wallet for storing verifiable credentials, for example, https://lcw.app/
EBSI — European Blockchain Services Infrastructure. It is a blockchain network of distributed nodes across Europe to support credentials applications. https://ec.europa.eu/digital-building-blocks/wikis/display/EBSI/What+is+ebsi
Existing Implementations
Repository with VC educational use cases – https://github.com/w3c-ccg/vc-ed-use-cases/issues
Example of issuing HTTP API https://w3c-ccg.github.io/vc-api/#issuing
Libraries to work with VC
DCC/MIT ecosystem
Other
JS - https://github.com/decentralized-identity/did-jwt-vc https://github.com/digitalbazaar/vc-js
Python - https://github.com/docknetwork/vcpy, Using active directory VC https://github.com/Azure-Samples/active-directory-verifiable-credentials-python
Rust - https://github.com/spruceid/didkit (with python bindings)
Verifiable Credentials in Education Cases
MIT xPRO and DC Wallet (DCC) integration details
Design Proposal
High-Level design
Overview: The main idea is to create a new Django application in the edX credentials service (https://github.com/openedx/credentials). This application will be capable of transforming Open edX credentials, such as program and course certificates, into digital and verifiable credentials, as well as sending generated credentials to learners' credentials wallets or digital badge system accounts.
The global verifiable credentials sharing functionality can be enabled by edx_toggles.toggles e.g., WaffleSwitch or DjangoSetting based on OEP-17
The administrator should enable a VC issuing for an Open edX credential, in Django admin (CourseCertificate/ProgramCertificate configuration) addresses Use Case ID #admin-004
The solution can be divided into separate units:
Issuer configuration (including specifying the private keys and credentials)
Issuing VC
Forming verifiable credentials or digital credentials using the learners' data
Invalidating VC (changing status)
Issuing digital credentials (badges)
Requirements:
An application should:
Have a possibility to configure an issuer info
Transform data from DB into JSON-LD claim
Be able to get learners and issuers data from DB (via API)
Sign VC, using an internal or an external signing module
Form a QR code or a deep-link to pass request parameters to the digital wallet app
Be open for integration with Digital Credentials Wallets and Digital Badges Platforms
Allow administrators to restrict which claims can be asserted #admin-004
Solution diagram
https://structurizr.com/share/72212/diagrams#SystemContext
source: https://github.com/raccoongang/verifiable-credentials-design/blob/main/c4_dsl/workspace.dsl
Implementation details
Issuer configuration (including specifying the private keys and credentials)
The system should be configurable.
This implementation must cover some system administrators' use cases
Django admin configuration
A system administrator should be able to restrict which claims can be asserted by course, program, degree, or organization. This can be achieved either by managing VC availability on CourseCertificate/ProgramCertificate configuration level or by creating a separate model for configuring general issuing policies.
Issuing VC
Restriction issuing request must be initiated by a digital credentials wallet. Issuing is happening directly to the wallet. Every wallet may have its integration solution.
Restriction To Integrate with DCC mobile wallet, the issuer must be added to the application issuers registry: https://github.com/digitalcredentials/learner-credential-wallet/blob/main/app/data/issuerAuth.ts
Issue a credential to DC learner wallet sequence diagram
MFE wireframes
The main idea of the issuing UI is to show to a user a list of acquired certificates, allow user to select one or several of them, and include data about completions into VC.
Inspired by My Certificates from the profile MFE and MITxPRO implementation
ref. https://projects.invisionapp.com/share/NE10C77DGTDB#/screens/446047647
Signing Credential
JSON-LD proof is selected as the main assertion format. Other rejected assertion formats can be found at the bottom of this page Verifiable Credentials integration - Solution Notes | Rejected alternatives
As the signing library, we decided to use python bindings to Rust-based library DIDKit.
DIDKit implements VC-api for signing and verifying credentials and can be used as is. (https://www.spruceid.dev/quickstart#step-1-issue-and-verify-your-first-vc-using-a-did)
DIDKit can be used natively with python through the PyO3 bindings. Here’s the example of using it in the Django application: https://github.com/spruceid/didkit-python/tree/main/examples/python_django
Adding credentials to a digital wallet
There are many wallets. Every wallet may need its algorithm for adding credentials.
DCC learner wallet https://github.com/digitalcredentials/learner-credential-wallet is an open-source implementation of the digital credential wallet, this application is used by MIT service MITxPRO.
MATTR Wallet is another good example of a digital credential wallet.
Mobile app:
The system generates and hands over request parameters
to the digital wallet mobile app using deeplink or QR code.
QR code library
It’s recommended to use djnago-qr library with is based on Segno by https://github.com/spruceid/didkit-python.
The comparison of alternatives can be found in Rejected alternatives section.
Deep link generation
MIT digitalcredentials library provides an utility function to generate deeplink and provide required parameters https://github.com/mitodl/ol-django/blob/main/src/mitol/digitalcredentials/backend.py#L96
Forming verifiable credentials or digital credentials using the learners' data
Verifiable credentials
Forming a verifiable credential means filling in credentialSubject
data https://www.w3.org/TR/vc-data-model/#credential-subject.
credentialSubject.ID
- the ID of the subject, who has received a credential. This is usually DID
of the learner's wallet.
It is possible to express information related to multiple subjects in a verifiable credential, for example, https://www.w3.org/TR/vc-data-model/#example-specifying-multiple-subjects-in-a-verifiable-credential.
Implementation for the course and program certificates for MITxPRO project:
Table 1. VC to Course/Program certificates mapping.
?
- There’s no corresponded value in the credentials service database
-
- This field can be skipped for this type of VC
VC | Open edX Course Certificate | Open edX Program Certificate |
---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
| constant: | constant: |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Comments
It’s not clear what to set for the field credentialSubject.hasCredential.awardedOnCompletionOf.numberOfCredits
.
In the EducationalOccupationalProgram schema, numberOfCredits
corresponds to credit in education based on Carnegie Unit or similar. We have CreditPathways for programs, but don't track that actual number of credits for that institution for that pathway. Is that data that we might need to collect somehow?
I think we either can skip this field from the schema for MVP, consider integration with CreditPathways, or get the value from the field set by Course/Program Creators.
Support OpenBadges3.0
OBv3 are supported now by both LC wallet and didkit-python.
To provide credentials in the form of OBv3 we should change the credentialSubject
object according to the specification - https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.1.json
Support EBSI
EBSI extends VC and adds Verifiable Attestation scheme to VC claim
https://ec.europa.eu/digital-building-blocks/wikis/display/EBSIDOC/Data+Models+and+Schemas
The list of conformant wallets: https://ec.europa.eu/digital-building-blocks/wikis/display/EBSI/Conformant+wallets
All implements use case Diploma https://ec.europa.eu/digital-building-blocks/wikis/display/EBSIDOC/Diploma+Functional+Scope
Invalidating VC (changing status)
The VC status list 2021 concept is the state of the art right now https://w3c-ccg.github.io/vc-status-list-2021/
Conceptual Framework (https://w3c-ccg.github.io/vc-status-list-2021/#conceptual-framework)
This section outlines the core concept utilized by the status list mechanism described in this document. At the most basic level, status information for all verifiable credentials issued by an issuer are expressed as simple binary values. The issuer keeps a bitstring list of all verifiable credentials it has issued. Each verifiable credential is associated with a position in the list. If the binary value of the position in the list is 1 (one), the verifiable credential is revoked, if it is 0 (zero) it is not revoked.
The example of the credentialStatus
{
"@context": [
"https://www.w3.org/2018/credentials/v1",
"https://w3id.org/vc/status-list/2021/v1"
],
"id": "https://example.com/credentials/23894672394",
"type": ["VerifiableCredential"],
"issuer": "did:example:12345",
"issued": "2021-04-05T14:27:42Z",
"credentialStatus": {
"id": "https://example.com/credentials/status/3#94567"
"type": "StatusList2021Entry",
"statusPurpose": "revocation",
"statusListIndex": "94567",
"statusListCredential": "https://example.com/credentials/status/3"
},
"credentialSubject": {
"id": "did:example:6789",
"type": "Person"
},
"proof": { ... }
}
Implementation of the credentials status in DIDKit https://github.com/spruceid/ssi/blob/e9f15acd89dad08c768e8fc009fb5bc5a76b2243/ssi-vc/src/revocation.rs#L459
The support for issuing credentials compliant with VC Status List 2021 was added to sign and verify services in https://github.com/digitalcredentials/sign-and-verify-core/pull/18
Implementation notes for Status List in Open edX
For the MVP, it was decided to implement status list as an API endpoint that is available out of the box. Deployers with Ops expertise can cache API responses regularly, and host it on CDN to address privacy concerns.
Issuing digital credentials (badges)
OpenBadgesv2.0
Current implementation of OpenBadges2.0 and badgr integtration: https://github.com/openedx/edx-platform/tree/master/lms/djangoapps/badges
https://edx.readthedocs.io/projects/edx-installing-configuring-and-running/en/latest/configuration/enable_badging.html
We may move this application to credentials.
There are several dependencies on edx-platform:
Modulestore can be replaced by adding this parameter to course metadata in the catalog
https://github.com/openedx/edx-platform/blob/master/xmodule/course_module.py#L607
in Events: get_completion_badge and course_badge_check
https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/badges/events/course_complete.py#L117BadgingService
https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/lms_xblock/runtime.py#L156Course Certificates dependencies
https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/certificates/views/webview.py#L444
Future possible enhancements
Integrate VC verifier to use VC as course prerequisites. https://github.com/digitalcredentials/sign-and-verify#verify-presentation, https://w3c-ccg.github.io/vc-api/#verifying
Integrate with other popular wallets
Integrate with edX skills ecosystem and taxonomy connector.
Provide credentials in different languages https://www.w3.org/TR/vc-data-model/#language-and-base-direction
Registering ISSUER?
Issuer
- can be represented as URI, DID, JWK or object with ID.
DCC issuer registry: https://github.com/digitalcredentials/docs/blob/main/identity/issuer_registry.md
Reference: https://www.w3.org/TR/did-spec-registries/#the-registration-process https://didproject.azurewebsites.net/docs/registration.html
Public keys sharing:
The verifier requires additional information about the issuer to trust. For example, an issuer can publish information containing the public keys it uses to digitally sign verifiable credentials that it issued. https://www.w3.org/TR/vc-data-model/#issuer-0
The verificationMethod
that included in the proof
property is the identifier of the public key that can verify the signature (URI)
publish /.well-known/did.json without a public key https://identity.foundation/.well-known/resources/did-configuration/
Rejected alternatives
Requirements:
Application should Store learners DIDs in DB.
As told by DCC member this is a bad practice.
Possible problems may be in case user changes the phone or reinstall the DCC wallet app. User’s DID is correspondent to specific wallet and might be changed over time.
Integrate with EDCI, xml protocol widely used in European universities.
XML/XSD model https://github.com/european-commission-empl/European-Learning-Model
Signing Credential
Assertion formats comparison:
JWT vs Linked data proofs – https://medium.com/mattr-global/jwt-vs-linked-data-proofs-comparing-vc-assertion-formats-a2a4e6671d57
https://w3c.github.io/vc-imp-guide/#benefits-of-json-ld-and-ld-proofs
ZKP solution from MATTR https://medium.com/mattr-global/a-solution-for-privacy-preserving-verifiable-credentials-f1650aa16093 – combination of the Linked Data Proofs with BBS+ signatures.
Selected solution: JSON-LD proof (different signing services may provide different signing methods.), rejected: JWT, ZKP, may be considered in the future.
Integrate sign-and-verify
DCC sign and verify service provides an API implementation for issuing credentials https://github.com/digitalcredentials/sign-and-verify#issue-credential
Possible ways to integrate with Signing Service:
Add independently deployed service to Open edX stack as sign and verify TypeScript REST API service from DCC
Integrate only with other signing platforms as MATTR, Microsoft Entra Verified ID…
Add RPC protocol to open-source JS app (as GRPC)
Implement sign-and-verify library in pure python
Currently, the first and the fourth variants are considered the most likely.
DCC sign and verify service provides an API implementation for issuing credentials https://github.com/digitalcredentials/sign-and-verify#issue-credential . However, sign-and-verify is a node service.
The preferred way to integrate with Signing Service is to add independently deployed service to Open edX stack as sign and verify TypeScript REST API service from DCC. Rejected alternatives for integrating with sign-and-verify can be found at the bottom of this page Verifiable Credentials integration - Solution Notes | Rejected alternatives
Another possible option is to implement a native python signing service to integrate with.
Static system configuration
The MIT library, digitalcredentials https://pypi.org/project/mitol-django-digital-credentials/ provides functionality to work with DCC https://github.com/digitalcredentials/sign-and-verify service and DCC Learners Wallet https://github.com/digitalcredentials/learner-credential-wallet
For now, it means we would be limited to only one ISSUER per Open edX installation.
DCC issuer registry: https://github.com/digitalcredentials/docs/blob/main/identity/issuer_registry.md
https://pypi.org/project/mitol-django-digital-credentials/ library requires a static setup for the next variables:
sign-and-verify service requires a static configuration for the following variables:
The issuer module is using provided parameters and generates public/private DID pair on application start-up (https://github.com/digitalcredentials/sign-and-verify/blob/main/src/app.ts#L86 ).
QR code library
There are listed other options to generate QR codes in python:
Based on small research, there are two popular libraries that provide QR code generation capabilities: Segno and python-qrcode.
According to comparison, Segno is faster and has no dependencies, unlike python-qrcode, which has a dependency on the Pillow library.
https://segno.readthedocs.io/en/stable/comparison-qrcode-libs.html
Wallets Integrations
To integrate with MATTR application, we need to use MATTR CORE platform as a signer, using REST API and secure DID messaging – https://medium.com/mattr-global/issuing-credentials-directly-to-the-mattr-mobile-wallet-8e8cab931e2e .
Adding credentials to a digital wallet
Web Wallet:
DCC has no integrations with web-based wallets for now.
https://tykn.tech/web-wallet/, https://walt.id/wallet-kit
Draft Notes:
Q: Does it required to get additional data from SSO IdP about subject?
Relying on authority sso, verifying SSO linked credentials (organization-specific registry and params)
Integration with the edX Credentials codebase
VC/OpenBadges3.0/EBSI use case | edX Credentials entity | Comments |
---|---|---|
Issue a credential |
| To be extended |
List user completions | CredentialViewSet | To be extended |
Select completions to include in the credential | - | To be created |
Repository with source files
https://github.com/raccoongang/verifiable-credentials-design