diff --git a/README.rst b/README.rst index 0eadf6910..ebab83314 100644 --- a/README.rst +++ b/README.rst @@ -1,20 +1,38 @@ -edX Credentials Service |Codecov|_ -==================================== +============================ +Open edX Credentials Service +============================ -.. |Codecov| image:: http://codecov.io/github/edx/credentials/coverage.svg?branch=master -.. _Codecov: http://codecov.io/github/edx/credentials?branch=master +| |status-badge| |license-badge| |CI| |Codecov| -This repository contains the edX Credentials Service, which supports course and program certificates. This service is a -replacement for the ``certificates`` app in ``edx-platform``. +.. |CI| image:: https://github.com/openedx/credentials/actions/workflows/ci.yml/badge.svg + :target: https://github.com/openedx/credentials/actions?query=workflow%3ACI + :alt: Test suite status -Credentials can be run as part of devstack_ or Tutor_ (using the tutor_credentials_ plugin). +.. |Codecov| image:: https://codecov.io/github/openedx/credentials/coverage.svg?branch=master + :target: https://codecov.io/github/openedx/credentials?branch=master + :alt: Code coverage -.. _devstack: https://github.com/openedx/devstack +.. |status-badge| image:: https://img.shields.io/badge/Status-Maintained-brightgreen + :alt: Maintained + +.. |license-badge| image:: https://img.shields.io/github/license/openedx/credentials.svg + :target: https://github.com/openedx/credentials/blob/master/LICENSE + :alt: License + +Purpose +======= + +This repository contains the Open edX Credentials Service, which supports course and program certificates. +This service is an extension to `openedx-platform`_ providing a set of unique features in the credentials domain such as Badges, Verifiable Credentials, Learning Records, and Program Certificates. + +The easiest way to run Credentials service is by using Tutor_, the community-supported, Docker-based Open edX distribution, by installing the tutor_credentials_ plugin. + +.. _openedx-platform: https://github.com/openedx/openedx-platform/tree/master .. _tutor: https://docs.tutor.edly.io/ .. _tutor_credentials: https://github.com/overhangio/tutor-credentials Where to run `make` commands --------------------------- +---------------------------- Due to the nature of developing in containers, some commands must be ran inside the container. Currently most commands can be ran either inside the container or inside a local virtual environement, once developer requirements have been @@ -102,3 +120,4 @@ Our real-time conversations are on Slack_. .. _`discussion forums`: https://discuss.openedx.org .. _Slack: http://openedx.slack.com/ + diff --git a/docs/_diagrams/sharing/credential_sharing.dsl b/docs/_diagrams/sharing/credential_sharing.dsl new file mode 100644 index 000000000..1f3eaa968 --- /dev/null +++ b/docs/_diagrams/sharing/credential_sharing.dsl @@ -0,0 +1,117 @@ +/* + * C4 model for the Credential Sharing feature in Open edX. + * Covers Digital Badges and Verifiable Credentials. + * + * Written in Structurizr DSL (https://structurizr.org/). + */ +workspace "Credential Sharing" { + + model { + siteAdmin = person "Site Admin" "Configures badge templates and VC issuing" + learner = person "Learner" "Earns credentials through learning activities" + verifier = person "Verifier" "Employer or institution that verifies learner credentials" + + digitalWallet = softwareSystem "Digital Wallet" "Learner Credential Wallet or compatible storage" + digitalBadgePlatform = softwareSystem "Digital Badge Platform" "Credly, Accredible" "Existing System" + + openedX = softwareSystem "Open edX" { + edxPlatform = container "openedx-platform" "LMS and course management" "Python/Django" + eventBus = container "Event Bus" "Redis Streams or Kafka" "" "Queue" + credentialsService = container "edX Credentials" "Stores learner achievements, issues credentials" "Python/Django" { + credentialsCore = component "Credentials Core" "Manages course and program certificates" "Django" + digitalBadgesIssuer = component "Digital Badges Issuer" "Processes badge requirements, issues badges to external platforms" "Django" + verifiableCredentialsIssuer = component "Verifiable Credentials Issuer" "Issues W3C Verifiable Credentials, signs with didkit (Ed25519)" "Django" + vcIssuerMFE = component "Learner Record MFE" "UI for learners to request verifiable credentials" "React" + } + credentialsDB = container "MySQL" "Credentials database" "" "Database" + } + + # --- Actors --- + + siteAdmin -> credentialsCore "Configures badge templates and VC settings" "Admin panel" + learner -> edxPlatform "Completes courses and assignments" + learner -> vcIssuerMFE "Requests verifiable credential" + + # --- Event Bus flows --- + + # LMS produces events consumed by Credentials + edxPlatform -> eventBus "Publishes certificate and course passing status events" "openedx-events" + eventBus -> credentialsCore "Delivers certificate and course grades events" "openedx-events" + eventBus -> digitalBadgesIssuer "Delivers badge-related events" "learning-badges-lifecycle topic" + + # Credentials produces events back to the bus + digitalBadgesIssuer -> eventBus "Publishes badges lifecycle events" "openedx-events" + + # --- Internal flows --- + + credentialsCore -> credentialsDB "Uses" "Django ORM" + digitalBadgesIssuer -> credentialsDB "Uses" "Django ORM" + verifiableCredentialsIssuer -> credentialsDB "Uses" "Django ORM" + + # --- External integrations --- + + # Badges + digitalBadgesIssuer -> digitalBadgePlatform "Issues and revokes badges" "REST API" + + # Verifiable Credentials + vcIssuerMFE -> verifiableCredentialsIssuer "Initiates VC issuance" + verifiableCredentialsIssuer -> digitalWallet "Sends signed verifiable credential" + digitalWallet -> verifiableCredentialsIssuer "Sends issuance request" "HTTP" + + # Verification + verifier -> verifiableCredentialsIssuer "Checks credential revocation status" "StatusList2021 API" + verifier -> digitalBadgePlatform "Checks badge revocation status" "" + + } + + views { + systemContext openedX "SystemContext" "High-level view of Credential Sharing" { + include * + autoLayout lr + } + + container openedX "Containers" "Open edX containers involved in credential sharing" { + include * + autoLayout lr + } + + component credentialsService "Components" "Credentials service internal components" { + include * + autoLayout lr + } + + styles { + element "Person" { + color "#ffffff" + background "#08427b" + fontSize 22 + shape Person + } + element "Software System" { + background "#1168bd" + color "#ffffff" + } + element "Existing System" { + background "#999999" + color "#ffffff" + } + element "Container" { + background "#438dd5" + color "#ffffff" + } + element "Component" { + background "#85bbf0" + color "#000000" + } + element "Database" { + shape Cylinder + } + element "Queue" { + shape Pipe + } + } + } + configuration { + scope softwaresystem + } +} diff --git a/docs/_static/images/sharing/credential_sharing_components.png b/docs/_static/images/sharing/credential_sharing_components.png new file mode 100644 index 000000000..7aa301c11 Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_components.png differ diff --git a/docs/_static/images/sharing/credential_sharing_containers.png b/docs/_static/images/sharing/credential_sharing_containers.png new file mode 100644 index 000000000..44800fcc8 Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_containers.png differ diff --git a/docs/_static/images/sharing/credential_sharing_system_context.png b/docs/_static/images/sharing/credential_sharing_system_context.png new file mode 100644 index 000000000..ee3e4f69c Binary files /dev/null and b/docs/_static/images/sharing/credential_sharing_system_context.png differ diff --git a/docs/_static/images/sharing/vc_lifecycle.png b/docs/_static/images/sharing/vc_lifecycle.png new file mode 100644 index 000000000..85059f473 Binary files /dev/null and b/docs/_static/images/sharing/vc_lifecycle.png differ diff --git a/docs/badges/configuration/accredible.rst b/docs/badges/configuration/accredible.rst deleted file mode 100644 index 3efbdbe62..000000000 --- a/docs/badges/configuration/accredible.rst +++ /dev/null @@ -1,172 +0,0 @@ -Accredible Configuration -======================== - -.. note:: - - This section provides information on how and where to set up accredible badge groups and configuration. - -The Badges feature is configured in the Credentials admin panel. - -.. image:: ../../_static/images/badges/badges-admin.png - :alt: Badges administration - -Accredible API Configurations ------------------------------ - -Multiple Accredible API Configurations can be configured. - -**All communication between Open edX Credentials and Accredible service happens on behalf of a Accredible API config.** - -Go to the Accredible API Configs section in the admin panel and create a new item: - -1. to set the name for config; -2. to set the api key, used to sync the Accredible account. - -In case of errors, check the credentials used for the API Config - -Groups ---------------- - -*Accredible groups* (badge templates for short) are created in the Accredible dashboard and then, they are retrieved by the Credentials via API. - -Synchronization -~~~~~~~~~~~~~~~ - -To synchronize Accredible groups for the API Configuration one should: - -- navigate "Accredible API Configs" list page; -- select the API Config; -- use ``Sync groups`` action; - -.. image:: ../../_static/images/badges/badges-admin-groups-sync.png - :alt: Accredible groups synchronization - -On success, the system will update the list of Accredible groups: - -- Accredible group records are created inactive (disabled); - -For a group to be considered during the processing it must be configured (to have at least 1 requirement) and activated (enabled) first. - -Badge Requirements ------------------- - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -Badge Requirement(s) specification is a crucial part of group configuration. -At least one badge requirement must be associated with a group. - -Badge Requirements are listed inline on a group detail page. - -.. image:: ../../_static/images/badges/badges-admin-template-requirements.png - :alt: Credly badge template requirements - -A badge template can have multiple requirements. All badge requirements must be *fulfilled* before the system will issue a badge to a learner. - -Event type -~~~~~~~~~~ - - Describes **what is expected to happen**. - -Available event type subset is pre-configured in the application settings. - -.. note:: - - Technically, any public signal from the `openedx-events`_ library can be used for badge template requirements setup, if it includes user PII (UserData), so users can be identified. - -Rules -~~~~~ - -A list of configured data rules (if any), see "Data Rules". - -Description -~~~~~~~~~~~ - -**Description** is an optional human-readable reminder that describes what the requirement is about. - - Badge Requirement can be **deeper specified** via its Data Rules. - -Group -~~~~~ - -Optional configuration (by default each badge requirement is assigned a separate Group). - -Allows putting 2 or more badge requirements as a Group. -Requirements group is fulfilled if any of its requirements is fulfilled. - - "OR" logic is applied inside a Group. - -.. image:: ../../_static/images/badges/badges-admin-rules-group.png - :alt: Badge requirement rules group - -See :ref:`Configuration examples for Badging`. - -Data Rules ----------- - - Describes **how it is expected to happen** - -Data Rules detail their parent Badge Requirement based on the expected event payload. - -To edit/update a Data Rule: - -- navigate to the Badge Requirement detail page (use ``Change`` inline link); -- find the "Data Rules" section and add a new item; - -.. image:: ../../_static/images/badges/badges-admin-requirement-rules.png - :alt: Badge requirement rules edit - -**Each data rule describes a single expected payload value:** - -All key paths are generated based on the event type specified for the parent Badge Requirement. - -.. image:: ../../_static/images/badges/badges-admin-data-rules.png - :alt: Badge requirement data rules - -1. **Key path** - payload path to the target attribute - - dot-separated string; - - each event type has its unique pre-defined set of key paths; -2. **Operator** - comparison operation to apply between expected and actual values; - - available operators: (payload) - - ``"="`` (equals); - - ``"!="`` (not equals); -3. **Expected value** - an expected value for the target attribute - - payload boolean positive values allowed: ``"true", "True", "yes", "Yes", "+"``; - - payload boolean negative values allowed: ``"false", "False", "no", "No", "-"``; - - -Please, see :ref:`Configuration examples for Badging` for clarity. - -Badge Penalties ---------------- - - Penalties allow badge progress resetting based on user activity. - -Badge penalties are optional. -There could be 0 or more badge penalties configured for a badge template. - -Each badge penalty is *targeted* to 1 or more badge requirements. -A penalty setup is similar to a badge requirement, but has different effect: it decreases badge progress for a user. - -When all penalty rules have been applied, a learner's progress towards a badge is reset. - -.. image:: ../../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalty rules edit - -Activation ----------- - -Configured group can be activated: - -- navigate to the group detail page; -- check ``Is active`` checkbox; - - Activated groups starts "working" immediately. - -Accredible group record includes: - -1. Core credential attributes; -2. Badge template credential attributes; -3. Accredible service attributes (dashboard link); -4. Configured requirements; - -.. _openedx-events: https://github.com/openedx/openedx-events \ No newline at end of file diff --git a/docs/badges/configuration/credly.rst b/docs/badges/configuration/credly.rst deleted file mode 100644 index 15aaeb82f..000000000 --- a/docs/badges/configuration/credly.rst +++ /dev/null @@ -1,194 +0,0 @@ -Credly Configuration -==================== - -.. note:: - - This section provides information on how and where to set up badge templates and organizations. - -The Badges feature is configured in the Credentials admin panel. - -.. image:: ../../_static/images/badges/badges-admin.png - :alt: Badges administration - -Credly Organizations --------------------- - -Multiple Credly Organizations can be configured. - -**All communication between Open edX Credentials and Credly service happens on behalf of a Credly Organization.** - -Go to the Credly Organization section in the admin panel and create a new item: - -1. to set the UUID use your Credly Organization identifier; -2. to set the authorization token, used to sync the Credly Organization. - -Check: the system pulls the Organization's details and updates its name. - -In case of errors, check the credentials used for the Organization - -Badge templates ---------------- - -*Credly badge templates* (badge templates for short) are created in the Credly Organization's dashboard and then, if published, they are retrieved by the Credentials via API. - -Webhooks -~~~~~~~~~~~~~~~ - -.. note:: - - Webhooks is a connection with Credly and external platform that allows your server to be notified about events occuring within Credly. - -Webhooks are set up on Credly management dashboard as Credly is a main initiator of the syncronization. - -You should be able to select an action from the list so that whenever the specified action occurs internally, the external system is alerted. - -Without this synchronization, the external system will not be notified of any significant changes (e.g. a badge template update, or a badge template has been archived) and may incorrectly issue erroneous or outdated badges. - -Synchronization -~~~~~~~~~~~~~~~ - -To synchronize Credly badge templates for the Organization one should: - -- navigate "Credly badge templates" list page; -- select the Organization; -- use ``Sync organization badge templates`` action; - -.. image:: ../../_static/images/badges/badges-admin-credly-templates-sync.png - :alt: Credly badge templates synchronization - -On success, the system will update the list of Credly badge templates for the Organization: - -- only badge templates with ``active`` state are pulled; -- Credly badge template records are created inactive (disabled); - -.. image:: ../../_static/images/badges/badges-admin-credly-templates-list.png - :alt: Credly badge templates list - -For a badge template to be considered during the processing it must be configured (to have at least 1 requirement) and activated (enabled) first. - -Badge Requirements ------------------- - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -Badge Requirement(s) specification is a crucial part of badge template configuration. -At least one badge requirement must be associated with a badge template. - -Badge Requirements are listed inline on a badge template detail page. - -.. image:: ../../_static/images/badges/badges-admin-template-requirements.png - :alt: Credly badge template requirements - -A badge template can have multiple requirements. All badge requirements must be *fulfilled* before the system will issue a badge to a learner. - -Event type -~~~~~~~~~~ - - Describes **what is expected to happen**. - -Available event type subset is pre-configured in the application settings. - -.. note:: - - Technically, any public signal from the `openedx-events`_ library can be used for badge template requirements setup, if it includes user PII (UserData), so users can be identified. - -Rules -~~~~~ - -A list of configured data rules (if any), see "Data Rules". - -Description -~~~~~~~~~~~ - -**Description** is an optional human-readable reminder that describes what the requirement is about. - - Badge Requirement can be **deeper specified** via its Data Rules. - -Group -~~~~~ - -Optional configuration (by default each badge requirement is assigned a separate Group). - -Allows putting 2 or more badge requirements as a Group. -Requirements group is fulfilled if any of its requirements is fulfilled. - - "OR" logic is applied inside a Group. - -.. image:: ../../_static/images/badges/badges-admin-rules-group.png - :alt: Badge requirement rules group - -See :ref:`Configuration examples for Badging`. - -Data Rules ----------- - - Describes **how it is expected to happen** - -Data Rules detail their parent Badge Requirement based on the expected event payload. - -To edit/update a Data Rule: - -- navigate to the Badge Requirement detail page (use ``Change`` inline link); -- find the "Data Rules" section and add a new item; - -.. image:: ../../_static/images/badges/badges-admin-requirement-rules.png - :alt: Badge requirement rules edit - -**Each data rule describes a single expected payload value:** - -All key paths are generated based on the event type specified for the parent Badge Requirement. - -.. image:: ../../_static/images/badges/badges-admin-data-rules.png - :alt: Badge requirement data rules - -1. **Key path** - payload path to the target attribute - - dot-separated string; - - each event type has its unique pre-defined set of key paths; -2. **Operator** - comparison operation to apply between expected and actual values; - - available operators: (payload) - - ``"="`` (equals); - - ``"!="`` (not equals); -3. **Expected value** - an expected value for the target attribute - - payload boolean positive values allowed: ``"true", "True", "yes", "Yes", "+"``; - - payload boolean negative values allowed: ``"false", "False", "no", "No", "-"``; - - -Please, see :ref:`Configuration examples for Badging` for clarity. - -Badge Penalties ---------------- - - Penalties allow badge progress resetting based on user activity. - -Badge penalties are optional. -There could be 0 or more badge penalties configured for a badge template. - -Each badge penalty is *targeted* to 1 or more badge requirements. -A penalty setup is similar to a badge requirement, but has different effect: it decreases badge progress for a user. - -When all penalty rules have been applied, a learner's progress towards a badge is reset. - -.. image:: ../../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalty rules edit - -Activation ----------- - -Configured badge template can be activated: - -- navigate to the badge template detail page; -- check ``Is active`` checkbox; - - Activated badge template starts "working" immediately. - -.. image:: ../../_static/images/badges/badges-admin-template-details.png - :alt: Badge template data structure - -Credly badge template record includes: - -1. Core credential attributes; -2. Badge template credential attributes; -3. Credly service attributes (state, dashboard link); -4. Configured requirements; - -.. _openedx-events: https://github.com/openedx/openedx-events \ No newline at end of file diff --git a/docs/badges/configuration/index.rst b/docs/badges/configuration/index.rst deleted file mode 100644 index 6fed4f3ec..000000000 --- a/docs/badges/configuration/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -Badging Configuration -====================== - -.. toctree:: - :maxdepth: 1 - - credly - accredible - -.. _Credly (by Pearson): https://info.credly.com/ \ No newline at end of file diff --git a/docs/badges/index.rst b/docs/badges/index.rst deleted file mode 100644 index 0885241d6..000000000 --- a/docs/badges/index.rst +++ /dev/null @@ -1,56 +0,0 @@ -Badges Information -======================= - - The Badges feature allows learners to earn achievements (badges) for their learning activities. - -- **Badge Template** is another kind of **credential**. -- **Badge** is another kind of **user credential**. - -Current Badges version is highly integrated with the `Credly (by Pearson)`_ and `Accredible`_ services, but it is fully prepared to be used separately. - -What is Credly? ---------------- - -**Credly** is a end-to-end solution for creating, issuing, and managing digital Credentials. Organizations use **Credly** to recognize their learners' achievements. -Learners can store badges in their Credly profile to visualize their professional success - which courses were completed and when. - -Badges provide employers and peers concrete evidence of what learners have -accomplished in order to earn their credential and what they are now capable of. -Digital badges are a great way to motivate learning and display a learner's -subsequent achievements. - -Badges are typically finer-grained than a traditional course certificate. They -are meant to introduce game mechanics to have more frequent sources of -motivation than one would get from a cumulative certificate. - -What is Accredible? --------------------- - -**Accredible** allows for the design and issuance of verifiable digital badges and -certificates that showcase acquired skills, earning criteria, and evidence of -learning. Learn more about Accredible on the `Accredible features page`_. - - -Glossary --------- - -1. **Badge template** – a template of a badge (with design, name, and description) that will be used in settings to set up special rules to create a badge for users to receive on the platform. - -2. **Authorization token** – It's a temporary key that verifies identity and authorizes resource access. A token can be computer-generated or hardware-based. A valid token allows a user to retain access to an online service or web application until the token expires. - -3. **UUID** – Universally Unique Identifier – is a value used to identify an object or entity on the internet uniquely. Depending on the specific mechanisms used, a UUID is either guaranteed to be different or is, at least, extremely likely to be different from any other UUID generated. - ----- - -.. toctree:: - :maxdepth: 2 - - quickstart - settings - configuration/index - examples - processing - -.. _Credly (by Pearson): https://info.credly.com/ -.. _Accredible: https://www.accredible.com/ -.. _Accredible features page: https://www.accredible.com/features \ No newline at end of file diff --git a/docs/badges/processing.rst b/docs/badges/processing.rst deleted file mode 100644 index e80dce16c..000000000 --- a/docs/badges/processing.rst +++ /dev/null @@ -1,104 +0,0 @@ -Badges Processing -================== - -Incoming events async processing happens in a separate event bus consumer process(es). -See the Event Bus documentation for details. - - -Events subscription -------------------- - -.. note:: - - Only explicitly configured `event types`_ take part in the processing. - -See Badges `default settings`_ for the default set of supported events. -Though, it is expected that any public signal from the `openedx-events`_ library can extend this set with a single requirement: its payload includes a learner PII (UserData object). - - -Learner identification ----------------------- - -.. note:: - - Each incoming event must be associated with a specific learner. - -The system tries to identify a learner by the `UserData` object in the event payload. -If the learner is not found, the event is ignored. - -The system also ensures that such learner exists in the Credentials (creates if needed). - - -Requirements analysis ---------------------- - -Since any requirement is associated with a single event type, all relevant requirements are collected for the incoming signal: - -1. appropriate event type; -2. active badge templates; - -Each requirement's rules are checked against the event payload. -Requirement processing is dropped as soon as the system recognizes not applying rules. - - -Progress update ---------------- - -Current learners' badge progress is stored in the ``Badge Progress`` record. - -.. note:: - - Since badge templates can have more than one requirement, the system should track intermediate progresses as well. - -Once all rules of the processed requirement apply, the system: - -1. ensures there is the badge progress record for the learner; -2. marks the requirement as fulfilled for the learner; - -.. image:: ../_static/images/badges/badges-admin-progress-records.png - :alt: Badge progress records - -If a Badge Progress is recognized as completed (all requirements for the badge template are fulfilled), the system initiates the awarding process. - - -Badge awarding --------------- - -.. note:: - - Once all requirements for the badge template are fulfilled, the system should award the badge. - -On badge progress completion, the system: - -1. creates an *internal* user credential record for the learner; -2. notifies (public signal) about new badge awarded; -3. tries to issue an *external* Credly badge for the learner; - -.. note:: - - The Badges application implements its extended ``UserCredential`` version (the CredlyBadge) to track external issuing state. Once the Credly badge is successfully issued the **CredlyBadge is updated with its UUID and state**. - -.. _event types: https://docs.openedx.org/projects/openedx-events/en/latest/ -.. _openedx-events: https://github.com/openedx/openedx-events -.. _default settings: settings.html#default-settings - -Badge revocation ----------------- - -Badges can also be revoked. Its a separete set of rules that need to be set up. - -1. Go to Badge Penalties section in admin panel (admin/badges/badge_pentalties). - -.. image:: ../_static/images/badges/badges-admin-penalty-rules.png - :alt: Badge penalties - -2. Select a certain requirement that was previously set up to link penalty - a. To know how to set up badge template requirements, go to the `Configuration`_ section. - -3. Note that all penalties have to be linked to a certain requirement, so that when that requirement is not fulfilled, system would know when to revoke the badge. - -.. _Configuration: configuration.html - -When a learner's badge is revoked by Credly, the Credentials IDA will be notified and will update it's internal records. The status of the badge will change from `awarded` to `revoked` upon successful revocation. - -The badge cannot be reissued once it has been revoked. diff --git a/docs/badges/quickstart.rst b/docs/badges/quickstart.rst deleted file mode 100644 index 011acd0f2..000000000 --- a/docs/badges/quickstart.rst +++ /dev/null @@ -1,183 +0,0 @@ -Badges Operator Quick Start -============================ - -.. note:: - - This section includes brief information about the feature – what to start with; where to set up credentials, etc. - -Currently Open edX supports two badge services: Credly and Accredible. - -0. Prerequisites – service account ----------------------------------- - -To start using this feature a Credly or Accredible account is necessary. - -For Credly: - -1. Register on Credly and create your account. -2. Create Organization in Credly. -3. Create at least 1 badge template and activate it. - - -For Accredible: - -1. Register on Accredible and create your account. -2. Create at least 1 group. - -1. Enable feature ------------------ - -Badges feature is optional and it is disabled by default. So, it must be enabled to be accessible. - -.. code-block:: - - # LMS service: - FEATURES["BADGES_ENABLED"] = True - - # Credentials service: - BADGES_ENABLED = True - -2. Configure integration -------------------------------- - -.. note:: - - For detailed information, go to the `Configuration`_ section. - -Go to the Credentials service admin panel and configure the integration with the service: - -Credly ------- - -1. In the admin panel go to /admin/badges/credly_organization to add Credly Organization. - a. Add UUID (unique identifier) for the Credly organization - b. Add the authorization token of the Credly organization. - -Please note that UUID and authorization token will be given to you during the creation of the Credly Organization on the Credly side - -Check: the system pulls the Organization's data and updates its name. - -Accredible ------------ - -1. Retrieve API Key from Accredible account settings. Go to the Accredible account settings -> Manage API Keys and create a new API Key. -2. In the admin panel go to ``/admin/badges/accredibleapiconfig`` to add Accredible Group. - a. Add API Key - b. Add name for configuration - -.. _Configuration: configuration.html - - -3. Synchronize badge templates ------------------------------- - Note: For detailed information, go to the `Configuration`_ section. - -Credly ------- - -From the “Credly Organizations” list, select the Organization(s) you want to use and select ``Sync organization badge templates`` action. - -The system pulls the list of badge templates from the Credly Organization. Navigate to the “Credly badge templates” list and check newly created templates. - -Accredible ----------- -From the Accredible API Configurations list, select the Configuration(s) you want to use and select ``Sync groups`` action. - -The system pulls the list of groups from the Accredible account. Navigate to the “Accredible groups” list and check newly created groups. - -.. _Configuration: configuration.html - -4. Setup badge requirements ---------------------------- - -.. note:: - - Requirements describe **what** and **how** must happen on the system to earn a badge. - -The crucial part of the badge template configuration is the requirements specification. At least one requirement must be associated with a badge template. - -Go to the first badge template details page (admin/badges/credly_badge_templates or admin/badges/accrediblegroup) and add requirements for it: - -1. find the “Badge Requirements” section; -2. add a new item and select an event type (what is expected to happen); - a. optionally, put a description; -3. save and navigate to the Requirement details (Change link); - a. optionally, specify data rules in the “Data Rules” section (how exactly it is expected to happen); -4. add a new item and describe the rule; -5. select a key path - specific data element; -6. select an operator - how to compare the value; -7. enter a value - expected parameter’s value. - -.. note:: - - A configuration for the badge template that must be issued on a specific course completion looks as following: - - - Requirement 1: - - event type: ``org.openedx.learning.course.passing.status.updated.v1`` - - description: ``On the Demo course completion.`` - - Data rule 1: - - key path: ``course.course_key`` - - operator: ``equals`` - - value: ``course-v1:edX+DemoX+Demo_Course`` - - Data rule 2: - - key path: ``is_passing`` - - operator: ``equals`` - - value: ``true`` - -It is possible to put more than one requirement in a badge template. - -5. Activate configured badge templates --------------------------------------- - - To active a badge template check the ``is active`` checkbox on its edit page. - -Once badge requirements are set up, it should be “enabled” to start “working”. - -Once enabled, the badge template will be active and ready. - -.. warning:: - - Configuration updates for active badge templates are discouraged since they may cause learners’ inconsistent experience. - -6. See users Badge Progress ---------------------------- - -Current badge progress can be seen in the “Badge progress records” section in the Credentials admin panel. - -Since badge templates can have more than one requirement, there can be partially completed badges. - -7. See awarded user credentials -------------------------------- - -Already earned badges are listed in the "Credly badges" or "Accredible badges" section of the admin panel. - -.. note:: - - This badge is an extended version of a user credential record. - -Once badge progress is complete (all requirements were *fulfilled*), the system: - -1. creates internal user credentials (CredlyBadge or AccredibleBadge); -2. notifies about the badge awarding (public signal); -3. requests Credly or Accredible service to issue the badge (API request). - -8. See issued badges ---------------------------- - -Earned internal badges (user credentials) spread to the badge service. - -On a successful badge issuing, the CredlyBadge or AccredibleBadge user credential is updated with its requisites: - -1. external UUID; -2. external state; - -The Credly badge is visible in the Credly service. -The Accredible badge is visible in the Accredible service. - - -9. Badge template withdrawal ----------------------------- - -Badge template can be deactivated by putting it in the inactive state (``is active`` checkbox). - -Inactive badge templates are ignored during the processing. diff --git a/docs/badges/settings.rst b/docs/badges/settings.rst deleted file mode 100644 index 4168279c5..000000000 --- a/docs/badges/settings.rst +++ /dev/null @@ -1,200 +0,0 @@ -Badging Settings -================= - -.. note:: - - You can find technical details on how to set up proper configurations for badges to be active in this section. - -Badges feature settings allow configuration: - -1. feature availability; -2. event bus public signals subset for badges; -3. the Credly service integration details (URLs, sandbox usage, etc.); -4. the Accredible service integration details (URLs, sandbox usage, etc.); - -You can use tutor plugin to setup all needed configurations: - -https://github.com/raccoongang/tutor-contrib-badges - - -Feature switch --------------- - -The Badges feature is under a feature switch (disabled by default). - -To enable the feature, update these settings as follows: - -.. code-block:: python - - # Platform services settings: - FEATURES["BADGES_ENABLED"] = True - - # Credentials service settings: - BADGES_ENABLED = True - - -Default settings ----------------- - -The feature has its configuration: - -.. code-block:: python - - # Credentials settings: - BADGES_CONFIG = { - # these events become available in requirements/penalties setup: - "events": [ - "org.openedx.learning.course.passing.status.updated.v1", - "org.openedx.learning.ccx.course.passing.status.updated.v1", - ], - # Credly integration: - "credly": { - "CREDLY_BASE_URL": "https://credly.com/", - "CREDLY_API_BASE_URL": "https://api.credly.com/v1/", - "CREDLY_SANDBOX_BASE_URL": "https://sandbox.credly.com/", - "CREDLY_SANDBOX_API_BASE_URL": "https://sandbox-api.credly.com/v1/", - "USE_SANDBOX": False, - }, - # Accredible integration: - "accredible": { - "ACCREDIBLE_BASE_URL": "https://dashboard.accredible.com/", - "ACCREDIBLE_API_BASE_URL": "https://api.accredible.com/v1/", - "ACCREDIBLE_SANDBOX_BASE_URL": "https://sandbox.dashboard.accredible.com/", - "ACCREDIBLE_SANDBOX_API_BASE_URL": "https://sandbox.api.accredible.com/v1/", - "USE_SANDBOX": False, - }, - - # requirements data rules: - "rules": { - "ignored_keypaths": [ - "user.id", - "user.is_active", - "user.pii.username", - "user.pii.email", - "user.pii.name", - ], - }, - } - -- ``events`` - explicit event bus signals list (only events with PII user data in payload are applicable). -- ``credly`` - Credly integration details. -- ``accredible`` - Accredible integration details. -- ``rules.ignored_keypaths`` - event payload paths to exclude from data rule options (see: Configuration_). - -Credly integration -~~~~~~~~~~~~~~~~~~ - -- USE_SANDBOX - enables Credly sandbox usage (development, testing); -- CREDLY_BASE_URL - Credly service host URL; -- CREDLY_API_BASE_URL - Credly API host URL; -- CREDLY_SANDBOX_BASE_URL - Credly sandbox host URL; -- CREDLY_SANDBOX_API_BASE_URL - Credly sandbox API host URL; - -Accredible integration -~~~~~~~~~~~~~~~~~~~~~~ -- USE_SANDBOX - enables Accredible sandbox usage (development, testing); -- ACCREDIBLE_BASE_URL - Accredible service host URL; -- ACCREDIBLE_API_BASE_URL - Accredible API host URL; -- ACCREDIBLE_SANDBOX_BASE_URL - Accredible sandbox host URL; - -Event bus settings ------------------- - - ``learning-badges-lifecycle`` is the event bus topic for all Badges related events. - -The Badges feature has updated event bus producer configurations for the Platform and the Credentials services. - -Source public signals -~~~~~~~~~~~~~~~~~~~~~ - -Platform's event bus producer configuration was extended with 2 public signals: - -1. information about the fact someone’s course grade was updated (allows course completion recognition); -2. information about the fact someone’s CCX course grade was updated (allows CCX course completion recognition). - -.. code-block:: python - - # Platform services settings: - EVENT_BUS_PRODUCER_CONFIG = { - ... - - "org.openedx.learning.course.passing.status.updated.v1": { - "learning-badges-lifecycle": { - "event_key_field": "course_passing_status.course.course_key", - "enabled": _should_send_learning_badge_events, - }, - }, - "org.openedx.learning.ccx.course.passing.status.updated.v1": { - "learning-badges-lifecycle": { - "event_key_field": "course_passing_status.course.course_key", - "enabled": _should_send_learning_badge_events, - }, - }, - } - -Emitted public signals -~~~~~~~~~~~~~~~~~~~~~~ - -The Badges feature introduced 2 own event types: - -1. information about the fact someone has earned a badge; -2. information about the fact someone's badge was revoked; - -.. code-block:: python - - # Credentials service settings: - EVENT_BUS_PRODUCER_CONFIG = { - ... - - "org.openedx.learning.badge.awarded.v1": { - "learning-badges-lifecycle": {"event_key_field": "badge.uuid", "enabled": True }, - }, - "org.openedx.learning.badge.revoked.v1": { - "learning-badges-lifecycle": {"event_key_field": "badge.uuid", "enabled": True }, - }, - } - -Consuming workers -~~~~~~~~~~~~~~~~~ - -.. note:: - - Consumers implementation depends on the used event bus. - -Event bus options: - -- Redis Streams -- Kafka -- ... - -The Credentials and the Platform services **produce** (push) their public signals as messages to the stream. - -To **consume** (pull) those messages a consumer process is required. - -Redis Streams -############# - -When the Redis Streams event bus is used, the ``-learning-badges-lifecycle`` stream is used for messages transport. - -For producing and consuming a single package (broker) is used - event-bus-redis_. - -"Event Bus Redis" is implemented as a Django application and provides a Django management command for consuming messages -(see all details in the package's README). - -.. code-block:: bash - - # Credentials service consumer example: - /edx/app/credentials/credentials/manage.py consume_events -t learning-badges-lifecycle -g credentials_dev --extra={"consumer_name":"credentials_dev.consumer1"} - - # LMS service consumer example: - /edx/app/edxapp/edx-platform/manage.py lms consume_events -t learning-badges-lifecycle -g lms_dev --extra={"consumer_name":"lms_dev.consumer1"} - -.. note:: - - **Credentials event bus consumer** is crucial for the Badges feature, since it is responsible for all incoming events processing. - - **LMS event bus consumer** is only required if LMS wants to receive information about badges processing results (awarding/revocation). - - -.. _Configuration: configuration.html -.. _event-bus-redis: https://github.com/openedx/event-bus-redis \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index 9f16300dc..58fd2865c 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -12,20 +12,19 @@ This repository contains the Open edX Credentials Service, used as the backend t overview getting_started - asset_pipeline - testing - internationalization - theming credentials_admin learner_records configuring_certificates - verifiable_credentials/overview + sharing/index + asset_pipeline + theming pathways analytics + testing + internationalization credentials_api event_bus edx_extensions lms_user_id program_completion_emails decisions - badges/index diff --git a/docs/sharing/badges/configuration/accredible.rst b/docs/sharing/badges/configuration/accredible.rst new file mode 100644 index 000000000..9518ee747 --- /dev/null +++ b/docs/sharing/badges/configuration/accredible.rst @@ -0,0 +1,42 @@ +.. _badges-accredible-configuration: + +Accredible Configuration +======================== + +.. _badges-accredible-api-configs: + +Accredible API Configurations +----------------------------- + +Multiple Accredible API Configurations can be configured. +All communication between Open edX Credentials and Accredible happens on behalf of an Accredible API config. + +Go to the Accredible API Configs section in the admin panel and create a new item: + +#. Set the **name** for the config. +#. Set the **API key** used to sync the Accredible account. + +If errors occur, verify the credentials used for the API Config. + +Groups +------ + +Accredible groups (the Accredible equivalent of badge templates) are created in the Accredible dashboard, then retrieved by the Credentials service via API. + +Synchronization +~~~~~~~~~~~~~~~ + +To synchronize Accredible groups for an API Configuration: + +#. Navigate to the "Accredible API Configs" list page. +#. Select the API Config. +#. Use the ``Sync groups`` action. + +.. figure:: ../../../_static/images/badges/badges-admin-groups-sync.png + :alt: Accredible groups synchronization + +On success, the system updates the list of Accredible groups. + +- New group records are created inactive (disabled). + +Configure requirements (see :ref:`badges-configuration-requirements`) and activate the group (see :ref:`badges-configuration-activation`) before it takes effect. diff --git a/docs/sharing/badges/configuration/credly.rst b/docs/sharing/badges/configuration/credly.rst new file mode 100644 index 000000000..41b3078bd --- /dev/null +++ b/docs/sharing/badges/configuration/credly.rst @@ -0,0 +1,60 @@ +.. _badges-credly-configuration: + +Credly Configuration +==================== + +.. _badges-credly-organizations: + +Credly Organizations +-------------------- + +Multiple Credly Organizations can be configured. +All communication between Open edX Credentials and Credly happens on behalf of a Credly Organization. + +Go to the Credly Organization section in the admin panel and create a new item: + +#. Set the **UUID** to your Credly Organization identifier. +#. Set the **authorization token** used to sync the Credly Organization. + +The system pulls the Organization's details and updates its name. +If errors occur, verify the credentials used for the Organization. + +Badge Templates +--------------- + +Credly badge templates are created in the Credly Organization's dashboard. +Once published, they are retrieved by the Credentials service via API. + +Webhooks +~~~~~~~~ + +.. note:: + + Webhooks connect Credly with an external platform so your server is notified about events within Credly. + +Webhooks are set up on the Credly management dashboard. Credly initiates the synchronization. + +Select an action from the list so that whenever the specified action occurs, your system is notified. +Without this synchronization, the external system will not learn about changes (e.g. a template update or archival) and may issue outdated badges. + +Synchronization +~~~~~~~~~~~~~~~ + +To synchronize Credly badge templates for an Organization: + +#. Navigate to the "Credly Organizations" list page. +#. Select the Organization. +#. Use the ``Sync organization badge templates`` action. + +.. figure:: ../../../_static/images/badges/badges-admin-credly-templates-sync.png + :alt: Credly badge templates synchronization + +On success, the system fetches all active badge templates from the Credly Organization (pagination is handled automatically). + +- Only badge templates with ``active`` state are pulled. +- New badge template records are created inactive (disabled). + +.. figure:: ../../../_static/images/badges/badges-admin-credly-templates-list.png + :alt: Credly badge templates list + +Configure requirements (see :ref:`badges-configuration-requirements`) and activate the template (see :ref:`badges-configuration-activation`) before it takes effect. diff --git a/docs/badges/examples.rst b/docs/sharing/badges/configuration/examples.rst similarity index 74% rename from docs/badges/examples.rst rename to docs/sharing/badges/configuration/examples.rst index 9be07a535..c5c0a4643 100644 --- a/docs/badges/examples.rst +++ b/docs/sharing/badges/configuration/examples.rst @@ -1,36 +1,36 @@ .. _Configuration examples for Badging: -Configuration examples for Badging -=================================== +Configuration Examples +====================== -These examples will show how to configure requirements and ``data rules`` for necessary use cases. +These examples show how to configure requirements and data rules for common use cases. .. note:: + Requirements in the **same group** use OR logic - any one of them fulfills the group. + Requirements in **different groups** use AND logic - all groups must be fulfilled. Any of the following examples can be combined for more specific use cases. +Course Completion +----------------- -Implemented use cases ----------------------- +ANY COURSE GRADE Update +~~~~~~~~~~~~~~~~~~~~~~~ + Triggers on any gradable interaction (e.g. submit button click) in any course. Rarely useful on its own. -1. ANY COURSE GRADE update -~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Not that useful. Any interaction (e.g. submit button click) with gradable block in any course leads to a badge. - -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On any grade update.`` -2. ANY COURSE completion -~~~~~~~~~~~~~~~~~~~~~~~~ +ANY COURSE Completion +~~~~~~~~~~~~~~~~~~~~~ - Requires **passing grade** for any course. Once course'd grade becomes "passing" after gradable problem submission, + Requires **passing grade** for any course. Once a course grade becomes "passing" after a gradable problem submission, a badge is awarded. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On any (not CCX) course completion.`` c. **Data rule 1**: @@ -39,26 +39,12 @@ Implemented use cases iii. value: ``true`` -3. ANY CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Requires **passing grade** for any CCX course. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` - b. description: ``On any CCX course completion.`` - c. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - - -4. ANY COURSE completion EXCEPT a specific course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ANY COURSE Completion EXCEPT a Specific Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Requires **passing grade** for any course **excluding** the "Demo" course. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On any course completion, but not the "Demo" course.`` c. **Data rule 1**: @@ -71,12 +57,12 @@ Implemented use cases iii. value: ``course-v1:edX+DemoX+Demo_Course`` -5. SPECIFIC COURSE completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +SPECIFIC COURSE Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~ Requires **passing grade** for exact course ("Demo" course). -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On the Demo course completion.`` c. **Data rule 1**: @@ -89,13 +75,13 @@ Implemented use cases iii. value: ``course-v1:edX+DemoX+Demo_Course`` -6. MULTIPLE SPECIFIC COURSES completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +MULTIPLE SPECIFIC COURSES Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ **All** specified courses must be completed. Different requirement groups force each requirement to be fulfilled. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On the "Demo" course completion.`` c. group: ``A`` @@ -108,7 +94,7 @@ Implemented use cases ii. operator: ``equals`` iii. value: ``course-v1:edX+DemoX+Demo_Course`` -2. **Requirement 2**: +- **Requirement 2**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On the "Other" course completion.`` c. group: ``B`` @@ -122,12 +108,63 @@ Implemented use cases iii. value: ``course-v1:edX+DemoX+OTHER_Course`` -7. SPECIFIC CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ONE OF MULTIPLE SPECIFIC COURSES Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + At least a single from the specified courses must be completed. + Grouped requirements are processed as **"ANY FROM A GROUP"**. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Demo" course completion.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``equals`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``equals`` + iii. value: ``course-v1:edX+DemoX+Demo_Course`` + +- **Requirement 2**: + a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` + b. description: ``On the "Other" course completion.`` + c. group: ``A`` + d. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``equals`` + iii. value: ``true`` + e. **Data rule 2**: + i. key path: ``course.course_key`` + ii. operator: ``equals`` + iii. value: ``course-v1:edX+DemoX+OTHER_Course`` + + +CCX Course Completion +--------------------- + + +ANY CCX Course Completion +~~~~~~~~~~~~~~~~~~~~~~~~~ + + Requires **passing grade** for any CCX course. + +- **Requirement 1**: + a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + b. description: ``On any CCX course completion.`` + c. **Data rule 1**: + i. key path: ``is_passing`` + ii. operator: ``equals`` + iii. value: ``true`` + + +SPECIFIC CCX Course Completion +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Requires **passing grade** for exact CCX course ("Demo CCX1" course). -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` b. description: ``On the Demo CCX1 course completion.`` c. **Data rule 1**: @@ -139,12 +176,12 @@ Implemented use cases ii. operator: ``equals`` iii. value: ``ccx-v1:edX+DemoX+Demo_Course+ccx@1`` -8. ANY CCX course completion ON a SPECIFIC MASTER course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ANY CCX Course Completion on a Specific Master Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Requires **passing grade** for any "child" CCX course that based on the master "Demo" course. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` b. description: ``On any Demo CCX course completion.`` c. **Data rule 1**: @@ -156,13 +193,12 @@ Implemented use cases ii. operator: ``equals`` iii. value: ``course-v1:edX+DemoX+Demo_Course`` -9. ANY CCX course completion ON a SPECIFIC MASTER course EXCEPT a SPECIFIC CCX course -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +ANY CCX Course Completion on a Specific Master Course Except a Specific CCX Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - Complicated. Requires **passing grade** for **any "child" CCX course** that based on the master "Demo" course, **excluding** the "Demo CCX2" course. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` b. description: ``On any Demo CCX course completion.`` c. **Data rule 1**: @@ -178,45 +214,13 @@ Implemented use cases ii. operator: ``not equals`` iii. value: ``ccx-v1:edX+DemoX+Demo_Course+ccx@2`` -10. ONE OF MULTIPLE SPECIFIC COURSES completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - At least a single from the specified courses must be completed. - Grouped requirements are processed as **"ANY FROM A GROUP"**. - -1. **Requirement 1**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Demo" course completion.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+Demo_Course`` - -2. **Requirement 2**: - a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` - b. description: ``On the "Other" course completion.`` - c. group: ``A`` - d. **Data rule 1**: - i. key path: ``is_passing`` - ii. operator: ``equals`` - iii. value: ``true`` - e. **Data rule 2**: - i. key path: ``course.course_key`` - ii. operator: ``equals`` - iii. value: ``course-v1:edX+DemoX+OTHER_Course`` - - -11. SPECIFIC MASTER course OR ANY of its CCX courses EXCEPT a SPECIFIC CCX course completion -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Specific Master Course OR Any of Its CCX Courses Except a Specific CCX Course +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here requirements 1 and 2 are grouped, so any of them lead to a badge. -1. **Requirement 1**: +- **Requirement 1**: a. event type: ``org.openedx.learning.course.passing.status.updated.v1`` b. description: ``On the "Demo" course completion OR...`` c. group: ``A`` @@ -229,7 +233,7 @@ Implemented use cases ii. operator: ``equals`` iii. value: ``course-v1:edX+DemoX+Demo_Course`` -2. **Requirement 2**: +- **Requirement 2**: a. event type: ``org.openedx.learning.ccx.course.passing.status.updated.v1`` b. description: ``...OR any Demo CCX courses completion EXCLUDING CCX3.`` c. group: ``A`` @@ -248,12 +252,16 @@ Implemented use cases ----- -Future work ------------ +Potential Use Cases +------------------- + +The following ideas are not yet implemented. If you have a use case for any of them, start a conversation on the `Open edX discussion forum`_. + +- Events set extension (e.g. "Email activation", "Profile data completion", "Course section completion") +- Repetitive events (e.g. "5 arbitrary courses completion") +- Prerequisite events (e.g. "5 specific courses completion in a specified order") +- Time-ranged events (e.g. "Arbitrary course completion during February 2022") +- Badge dependencies (e.g. "Badge A + Badge B = Badge C") +- Multiple same badge earning (e.g. "3 arbitrary course completions make badge earned x3") -1. Events set extension (e.g. "Email activation", "Profile data completion", "Course section completion", ...); -2. Repetitive events (e.g. "5 arbitrary courses completion"); -3. Prerequisite events (e.g. "5 specific courses completion in a specified order"); -4. Time-ranged event (e.g. "Arbitrary course completion during the February 2022"); -5. Badge dependencies (e.g. "Badge A + Badge B = Badge C"); -6. Multiple times same badge earning (e.g. "3 arbitrary course completions make badge earned x3"); +.. _Open edX discussion forum: https://discuss.openedx.org/ diff --git a/docs/sharing/badges/configuration/index.rst b/docs/sharing/badges/configuration/index.rst new file mode 100644 index 000000000..1b09be04d --- /dev/null +++ b/docs/sharing/badges/configuration/index.rst @@ -0,0 +1,146 @@ +.. _badges-configuration: + +Badging Configuration +===================== + +Badge templates, requirements, rules, and penalties are configured in the Credentials admin panel. +Each badge template needs at least one requirement and must be activated before it takes effect. + +.. figure:: ../../../_static/images/badges/badges-admin.png + :alt: Badges administration + +Provider Setup +-------------- + +Provider setup (organization credentials, template synchronization) differs per badging provider. + +.. toctree:: + :maxdepth: 1 + + credly + accredible + examples + +.. _badges-configuration-requirements: + +Badge Requirements +------------------ + +Requirements describe what must happen for a learner to earn a badge. +At least one requirement must be associated with a badge template. + +Badge requirements are listed inline on the badge template detail page. + +.. figure:: ../../../_static/images/badges/badges-admin-template-requirements.png + :alt: Badge template requirements + +A badge template can have multiple requirements. +All requirements must be *fulfilled* before the system issues a badge. + +.. _badges-configuration-groups: + +Each requirement has the following fields. + +- **Event type** - the event that must occur. Available event types are pre-configured in the application settings. +- **Rules** - a list of configured data rules (if any). See :ref:`badges-configuration-data-rules`. +- **Description** - an optional human-readable reminder about the requirement's purpose. +- **Group** - by default each requirement belongs to its own group. You can assign two or more requirements to the same group - the group is fulfilled when *any* of its requirements is fulfilled ("OR" logic inside a group). + +.. figure:: ../../../_static/images/badges/badges-admin-rules-group.png + :alt: Badge requirement rules group + +.. note:: + + Any public signal from the `openedx-events`_ library can be used, provided it includes user PII (``UserData``) so learners can be identified. + +See :ref:`Configuration examples for Badging`. + +.. _badges-configuration-data-rules: + +Data Rules +---------- + +Data rules narrow a badge requirement based on the expected event payload. + +To add or edit a data rule: + +#. Navigate to the badge requirement detail page (use the ``Change`` inline link). +#. Find the "Data Rules" section and add a new item. + +.. figure:: ../../../_static/images/badges/badges-admin-requirement-rules.png + :alt: Badge requirement rules edit + +Each data rule describes a single expected payload value. +Key paths are generated from the event type of the parent requirement. + +.. figure:: ../../../_static/images/badges/badges-admin-data-rules.png + :alt: Badge requirement data rules + +.. list-table:: + :widths: 20 80 + :header-rows: 1 + + * - Field + - Description + * - **Key path** + - Dot-separated path to the target attribute. Each event type has a pre-defined set of key paths. + * - **Operator** + - Comparison operation: ``"="`` (equals) or ``"!="`` (not equals). + * - **Expected value** + - The value to compare against. + +.. note:: + + For boolean fields, the following string values are accepted: + + - **True:** ``"true"``, ``"True"``, ``"yes"``, ``"Yes"``, ``"+"`` + - **False:** ``"false"``, ``"False"``, ``"no"``, ``"No"``, ``"-"`` + +See :ref:`Configuration examples for Badging` for details. + +.. _badges-configuration-penalties: + +Badge Penalties +--------------- + +Penalties reset badge progress based on learner activity. +They are optional - a badge template can have zero or more. + +Each penalty targets one or more badge requirements. +A penalty uses the same structure as a requirement, but *decreases* progress instead of advancing it. +When all penalty rules match, the learner's progress toward the badge resets. + +.. figure:: ../../../_static/images/badges/badges-admin-penalty-rules.png + :alt: Badge penalty rules edit + +.. _badges-configuration-activation: + +Activation +---------- + +After configuring requirements, activate the badge template: + +#. Navigate to the badge template detail page. +#. Check the ``Is active`` checkbox. + +.. important:: + + An activated badge template starts working immediately. + +.. figure:: ../../../_static/images/badges/badges-admin-template-details.png + :alt: Badge template detail page + +.. list-table:: + :widths: 50 50 + :header-rows: 0 + + * - Core credential attributes + - Shared across all credential types. + * - Badge template credential attributes + - Specific to badges. + * - Provider-specific attributes + - State, dashboard link, etc. Varies by provider (see :ref:`badges-credly-configuration` or :ref:`badges-accredible-configuration`). + * - Configured requirements + - See :ref:`badges-configuration-requirements`. + +.. _openedx-events: https://github.com/openedx/openedx-events diff --git a/docs/sharing/badges/index.rst b/docs/sharing/badges/index.rst new file mode 100644 index 000000000..002ad8276 --- /dev/null +++ b/docs/sharing/badges/index.rst @@ -0,0 +1,52 @@ +Digital Badges +============== + +A digital badge is a credential that embeds metadata (issuer, criteria, +evidence) following the `Open Badges`_ standard. Badges can represent +individual achievements such as completing a course or passing an exam. + +The Badges feature issues badges through external providers. Built-in +support includes `Credly (by Pearson)`_ and `Accredible`_, with the +ability to add custom providers. + +Key concepts +------------ + +**Badge template** + Defines a badge's design, name, and awarding rules. Called "group" in + Accredible. + +**Badge** + The credential a learner earns when they fulfill all requirements of a + badge template. + +**Requirement** + A condition that must be met to earn a badge, tied to a specific event + type (e.g. course completion). + +**Data rule** + A filter on a requirement's event payload + (e.g. ``course.course_key equals course-v1:edX+DemoX``). + +**Group** + Requirements in the same group use OR logic (any one fulfills the group). + Requirements in different groups use AND logic. + +**Penalty** + A rule that resets badge progress when a learner no longer meets a + requirement (e.g. grade drops below passing). + +---- + +.. toctree:: + :maxdepth: 2 + + quickstart + settings + configuration/index + processing + management + +.. _Open Badges: https://openbadges.org/ +.. _Credly (by Pearson): https://info.credly.com/ +.. _Accredible: https://www.accredible.com/ diff --git a/docs/sharing/badges/management.rst b/docs/sharing/badges/management.rst new file mode 100644 index 000000000..24eecf327 --- /dev/null +++ b/docs/sharing/badges/management.rst @@ -0,0 +1,94 @@ +Managing Badges +=============== + +Synchronizing Badge Templates +----------------------------- + +Badge templates (Credly) and groups (Accredible) are created on the +provider's side and then pulled into the Credentials service through a +sync action in the admin panel. + +For **Credly**: + +#. Select one or more organizations on the "Credly Organizations" list page. +#. Run the ``Sync organization badge templates`` action. + +Only badge templates with ``active`` state on Credly are pulled. +See :ref:`badges-credly-configuration` for details. + +For **Accredible**: + +#. Select one or more configurations on the "Accredible API Configs" list + page. +#. Run the ``Sync groups`` action. + +See :ref:`badges-accredible-configuration` for details. + +.. note:: + + Synchronized templates and groups are created **inactive** by + default. Configure requirements and activate them before they + take effect. See :ref:`badges-configuration-activation`. + +Badge Progress +-------------- + +Current badge progress is visible in the "Badge progress records" +section of the Credentials admin panel. + +Badge templates can have more than one requirement, so there can +be partially completed badges. See :ref:`badges-processing` for +details on how progress is tracked. + +Awarded Credentials +------------------- + +Earned badges are listed in the provider-specific section of the admin panel. + +.. note:: + + Each badge is an extended version of a user credential record. + +Once badge progress is complete (all requirements are *fulfilled*), +the system awards the badge. See :ref:`badges-processing` for the +full awarding pipeline. + +The system: + +#. Creates an internal user credential record for the learner. +#. Emits a public signal about the badge award. +#. Sends an API request to the badge provider to issue the badge externally. + +Issued Badges +------------- + +After a badge is awarded internally, the system sends an API request to +the badge provider to issue the badge on their platform. + +On successful issuing, the badge record in the admin panel is updated with: + +#. **external UUID** - the identifier assigned by the provider. +#. **external state** - the badge status on the provider's side + (e.g. ``accepted``). + +The issued badge then appears in the provider's dashboard and is visible +to the learner. + +Badge Template Withdrawal +------------------------- + +Deactivate a badge template by unchecking the ``is active`` checkbox +on its edit page. See :ref:`badges-configuration` for activation details. + +Inactive badge templates are ignored during processing. + +.. seealso:: + + :ref:`badges-configuration` + Configure badge templates, requirements, and data rules. + + :ref:`badges-settings` + Feature switches and integration settings. + + :ref:`badges-processing` + How incoming events are processed and badges are awarded. diff --git a/docs/sharing/badges/processing.rst b/docs/sharing/badges/processing.rst new file mode 100644 index 000000000..f8177e3d8 --- /dev/null +++ b/docs/sharing/badges/processing.rst @@ -0,0 +1,90 @@ +.. _badges-processing: + +Badges Processing +================== + +Incoming events are processed asynchronously in a separate event bus consumer process. +See the Event Bus documentation for details. + + +Events subscription +------------------- + +Only explicitly configured `event types`_ take part in the processing. +See :ref:`badges-settings` for the default set of supported events. +Any public signal from the `openedx-events`_ library can extend this set, +provided its payload includes learner PII (``UserData`` object). + + +Learner identification +---------------------- + +The system identifies a learner by the ``UserData`` object in the event +payload. If the learner is not found, the event is ignored. The system also +ensures that the learner exists in the Credentials service (creates if needed). + + +Requirements analysis +--------------------- + +Since any requirement is associated with a single event type, all relevant +requirements are collected for the incoming signal: + +1. appropriate event type; +2. active badge templates; + +Each requirement's rules are checked against the event payload. +Requirement processing is skipped as soon as any rule doesn't match. + + +Progress update +--------------- + +Current learners' badge progress is stored in the ``Badge Progress`` record. +Badge templates can have more than one requirement, so the system tracks +intermediate progress. + +Once all rules of the processed requirement apply, the system: + +1. ensures there is the badge progress record for the learner; +2. marks the requirement as fulfilled for the learner; + +.. figure:: ../../_static/images/badges/badges-admin-progress-records.png + :alt: Badge progress records + +If a Badge Progress is recognized as completed (all requirements for the +badge template are fulfilled), the system initiates the awarding process. + + +Badge awarding +-------------- + +On badge progress completion, the system: + +1. creates an *internal* user credential record for the learner; +2. notifies (public signal) about new badge awarded; +3. tries to issue an *external* badge for the learner; + +The Badges application implements extended ``UserCredential`` versions +(``CredlyBadge`` and ``AccredibleBadge``) to track external issuing state. +Once a badge is successfully issued, the corresponding record is updated +with its external UUID and state. + +.. _event types: https://docs.openedx.org/projects/openedx-events/en/latest/ +.. _openedx-events: https://github.com/openedx/openedx-events + +Badge revocation +---------------- + +Badges can be revoked through badge penalties - rules that reset progress +when a requirement is no longer fulfilled. See the :ref:`badges-configuration` +section for penalty setup. + +Each penalty is linked to a specific requirement. When the penalty conditions +match, the system resets the learner's progress for that requirement. + +When a badge is revoked, the system updates its internal records. +For Credly, status changes from ``awarded`` to ``revoked``. +For Accredible, status changes from ``awarded`` to ``expired``. + +A badge cannot be reissued once revoked. diff --git a/docs/sharing/badges/quickstart.rst b/docs/sharing/badges/quickstart.rst new file mode 100644 index 000000000..c508a5269 --- /dev/null +++ b/docs/sharing/badges/quickstart.rst @@ -0,0 +1,124 @@ +Quick Start +=========== + +.. note:: + + Open edX supports two badge providers: Credly and Accredible. Both use the same concept - a **badge template** defines the badge design and awarding rules. Credly calls these "badge templates"; Accredible calls them "groups." This guide uses "badge template" as the generic term. + +.. contents:: Steps + :local: + :class: no-bullets + +Prerequisites +------------- + +To start using this feature a Credly or Accredible account is necessary. + +For Credly: + +#. Register on Credly and create your account. +#. Create Organization in Credly. +#. Create at least 1 badge template and activate it. + +For Accredible: + +#. Register on Accredible and create your account. +#. Create at least 1 group. + +1. Enable badges +---------------- + +Badges feature is optional and disabled by default. Enable it in both services. + +.. code-block:: python + + # openedx-platform (LMS) settings: + FEATURES["BADGES_ENABLED"] = True + + # Credentials service settings: + BADGES_ENABLED = True + +2. Configure integration +------------------------ + +Go to the Credentials service admin panel and configure the integration. + +For **Credly**: + +#. Go to ``/admin/badges/credlyorganization/`` to add Credly Organization. + + a. Add UUID (unique identifier) for the Credly organization. + b. Add the authorization token of the Credly organization. + +#. Verify the system pulls the Organization's data and updates its name. + +For **Accredible**: + +#. Retrieve API Key from Accredible account settings (Manage API Keys). +#. Go to ``/admin/badges/accredibleapiconfig/`` to add Accredible configuration. + + a. Add API Key. + b. Add name for configuration. + +See :ref:`badges-configuration` for details. + +3. Synchronize badge templates +------------------------------ + +For **Credly**: + +#. From the "Credly Organizations" list, select the Organization(s) you want to use. +#. Run the ``Sync organization badge templates`` action. +#. Navigate to the "Credly badge templates" list and verify the newly created templates. + +For **Accredible**: + +#. From the "Accredible API Configurations" list, select the Configuration(s) you want to use. +#. Run the ``Sync groups`` action. +#. Navigate to the "Accredible groups" list and verify the newly created groups. + +4. Setup badge requirements +--------------------------- + +Requirements describe what and how something must happen on the system to +earn a badge. At least one requirement must be associated with a badge +template. In the Credentials admin panel, open the badge template details +page: + +#. Find the "Badge Requirements" section. +#. Add a new item and select an event type (what is expected to happen). + + - Optionally, add a description. + +#. Save and navigate to the Requirement details page (use the "Change" link in the admin). + + - Optionally, specify data rules in the "Data Rules" section: + +#. Select a key path (specific data element). +#. Select an operator (how to compare the value). +#. Enter a value (expected parameter's value). + +A badge template can have more than one requirement. For example, a badge +template issued on a specific course completion: + +- Requirement 1: + - event type: ``org.openedx.learning.course.passing.status.updated.v1`` + - description: ``On the Demo course completion.`` +- Data rule 1: + - key path: ``course.course_key`` + - operator: ``equals`` + - value: ``course-v1:edX+DemoX+Demo_Course`` +- Data rule 2: + - key path: ``is_passing`` + - operator: ``equals`` + - value: ``true`` + +5. Activate badge templates +--------------------------- + +#. In the Credentials admin panel, navigate to the badge template edit page. +#. Check the ``is active`` checkbox. + +.. warning:: + + Configuration updates for active badge templates are discouraged since they may cause inconsistent learner experience. diff --git a/docs/sharing/badges/settings.rst b/docs/sharing/badges/settings.rst new file mode 100644 index 000000000..4708f5f34 --- /dev/null +++ b/docs/sharing/badges/settings.rst @@ -0,0 +1,237 @@ +.. _badges-settings: + +Badging Settings +================= + +These settings control the Badges feature: availability, event subscriptions, and provider integration (Credly, Accredible). + +.. tip:: + + The `tutor-contrib-badges`_ plugin configures all required settings automatically. The reference below is for manual or customized deployments. + +.. _tutor-contrib-badges: https://github.com/raccoongang/tutor-contrib-badges + + +Feature Switch +-------------- + +The Badges feature is disabled by default. Enable it in both services. + +.. code-block:: python + + # openedx-platform (LMS) settings: + FEATURES["BADGES_ENABLED"] = True + + # Credentials service settings: + BADGES_ENABLED = True + + +``BADGES_CONFIG`` Reference +---------------------------- + +``BADGES_CONFIG`` is the main configuration dictionary for the Credentials service. + +.. code-block:: python + + BADGES_CONFIG = { + "events": [ + "org.openedx.learning.course.passing.status.updated.v1", + "org.openedx.learning.ccx.course.passing.status.updated.v1", + ], + "credly": { + "CREDLY_BASE_URL": "https://credly.com/", + "CREDLY_API_BASE_URL": "https://api.credly.com/v1/", + "CREDLY_SANDBOX_BASE_URL": "https://sandbox.credly.com/", + "CREDLY_SANDBOX_API_BASE_URL": "https://sandbox-api.credly.com/v1/", + "USE_SANDBOX": False, + }, + "accredible": { + "ACCREDIBLE_BASE_URL": "https://dashboard.accredible.com/", + "ACCREDIBLE_API_BASE_URL": "https://api.accredible.com/v1/", + "ACCREDIBLE_SANDBOX_BASE_URL": "https://sandbox.dashboard.accredible.com/", + "ACCREDIBLE_SANDBOX_API_BASE_URL": "https://sandbox.api.accredible.com/v1/", + "USE_SANDBOX": False, + }, + "rules": { + "ignored_keypaths": [ + "user.id", + "user.is_active", + "user.pii.username", + "user.pii.email", + "user.pii.name", + "course.display_name", + "course.start", + "course.end", + ], + }, + } + +Top-level keys +~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Key + - Description + * - ``events`` + - Event bus signals available for requirements and penalties. Only events whose payload includes learner PII (``UserData``) are applicable. + * - ``credly`` + - Credly provider URLs and sandbox toggle (see below). + * - ``accredible`` + - Accredible provider URLs and sandbox toggle (see below). + * - ``rules.ignored_keypaths`` + - Event payload paths excluded from data rule options in the admin UI (see :ref:`badges-configuration`). + +Credly Settings +~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Setting + - Description + * - ``USE_SANDBOX`` + - Use Credly sandbox environment for development and testing. + * - ``CREDLY_BASE_URL`` + - Credly production host URL. + * - ``CREDLY_API_BASE_URL`` + - Credly production API URL. + * - ``CREDLY_SANDBOX_BASE_URL`` + - Credly sandbox host URL. + * - ``CREDLY_SANDBOX_API_BASE_URL`` + - Credly sandbox API URL. + +Accredible Settings +~~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 35 65 + + * - Setting + - Description + * - ``USE_SANDBOX`` + - Use Accredible sandbox environment for development and testing. + * - ``ACCREDIBLE_BASE_URL`` + - Accredible production host URL. + * - ``ACCREDIBLE_API_BASE_URL`` + - Accredible production API URL. + * - ``ACCREDIBLE_SANDBOX_BASE_URL`` + - Accredible sandbox host URL. + * - ``ACCREDIBLE_SANDBOX_API_BASE_URL`` + - Accredible sandbox API URL. + + +Event Bus Configuration +----------------------- + +.. tip:: + + If you use the `tutor-contrib-badges`_ plugin, event bus configuration is handled automatically. This section is for custom deployments. + +All badge-related events use the ``learning-badges-lifecycle`` topic. + +Source Signals (LMS) +~~~~~~~~~~~~~~~~~~~~ + +The LMS produces two signals that trigger badge processing. + +.. list-table:: + :header-rows: 1 + :widths: 55 45 + + * - Signal + - Purpose + * - ``org.openedx.learning.course.passing.status.updated.v1`` + - Course grade updated - enables course completion recognition. + * - ``org.openedx.learning.ccx.course.passing.status.updated.v1`` + - CCX course grade updated - enables CCX course completion recognition. + +.. code-block:: python + + # openedx-platform (LMS) settings: + EVENT_BUS_PRODUCER_CONFIG = { + ... + "org.openedx.learning.course.passing.status.updated.v1": { + "learning-badges-lifecycle": { + "event_key_field": "course_passing_status.course.course_key", + "enabled": _should_send_learning_badge_events, + }, + }, + "org.openedx.learning.ccx.course.passing.status.updated.v1": { + "learning-badges-lifecycle": { + "event_key_field": "course_passing_status.course.course_key", + "enabled": _should_send_learning_badge_events, + }, + }, + } + +Emitted Signals (Credentials) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The Credentials service emits two signals after badge processing completes. + +.. list-table:: + :header-rows: 1 + :widths: 55 45 + + * - Signal + - Purpose + * - ``org.openedx.learning.badge.awarded.v1`` + - A badge was awarded to a learner. + * - ``org.openedx.learning.badge.revoked.v1`` + - A badge was revoked from a learner. + +.. code-block:: python + + # Credentials service settings: + EVENT_BUS_PRODUCER_CONFIG = { + ... + "org.openedx.learning.badge.awarded.v1": { + "learning-badges-lifecycle": { + "event_key_field": "badge.uuid", + "enabled": BADGES_ENABLED, + }, + }, + "org.openedx.learning.badge.revoked.v1": { + "learning-badges-lifecycle": { + "event_key_field": "badge.uuid", + "enabled": BADGES_ENABLED, + }, + }, + } + +These signals are only produced when ``BADGES_ENABLED`` is ``True``. + +Consumer Setup +~~~~~~~~~~~~~~ + +The consumer implementation depends on your event bus backend (Redis Streams, Kafka, etc.). + +Both the Credentials and LMS services **produce** messages to the event stream. A separate **consumer** process pulls and handles those messages. + +**Redis Streams** - uses the event-bus-redis_ package, which provides a Django management command. + +.. code-block:: bash + + # Run in the Credentials service (required for badge processing): + ./manage.py consume_events \ + -t learning-badges-lifecycle \ + -g credentials_dev \ + --extra='{"consumer_name": "credentials_dev.consumer1"}' + + # Run in the openedx-platform (LMS) (optional - only if LMS needs badge award/revoke notifications): + ./manage.py lms consume_events \ + -t learning-badges-lifecycle \ + -g lms_dev \ + --extra='{"consumer_name": "lms_dev.consumer1"}' + +.. important:: + + The **Credentials consumer** is required - it processes all incoming badge events. The **LMS consumer** is optional and only needed if LMS should react to badge award or revocation signals. + + +.. _event-bus-redis: https://github.com/openedx/event-bus-redis diff --git a/docs/sharing/index.rst b/docs/sharing/index.rst new file mode 100644 index 000000000..ddc277e84 --- /dev/null +++ b/docs/sharing/index.rst @@ -0,0 +1,47 @@ +Credential Sharing +################## + +Open edX Credentials service supports multiple ways to share and +recognize learner achievements beyond traditional certificates. +Learners and institutions can distribute verified credentials to +third-party platforms, professional networks, and digital wallets. + +This section covers two sharing mechanisms. + +- **Digital Badges** - issue digital badges through providers like + `Credly `_ and + `Accredible `_. Badges recognize + specific achievements like course completions or skill milestones + and can be displayed on LinkedIn, personal websites, and other + platforms. +- **Verifiable Credentials** - issue W3C-compliant verifiable + credentials that learners store in digital wallets. These + credentials are cryptographically signed and independently + verifiable without contacting the issuer. + +Architecture +************ + +Three roles interact with the credential sharing system: **Site Admins** +configure badge templates and VC issuing, **Learners** complete courses and +earn credentials, and **Verifiers** (employers, institutions) check credential +revocation status. Credentials flow to external Digital Wallets and Digital +Badge Platforms. + +.. figure:: ../_static/images/sharing/credential_sharing_system_context.png + :alt: C4 System Context diagram showing Open edX credential sharing with actors (Site Admin, Learner, Verifier) and external systems (Digital Wallet, Digital Badge Platform). + +Inside the platform, the openedx-platform (LMS) publishes certificate and +course-passing events to the Event Bus. The Credentials service consumes these +events, stores achievement data in its database, issues and revokes badges on +external platforms via REST API, and sends signed verifiable credentials to +learner wallets. + +.. figure:: ../_static/images/sharing/credential_sharing_containers.png + :alt: C4 Container diagram showing Open edX internals: openedx-platform, Event Bus, edX Credentials service, MySQL database, and external integrations. + +.. toctree:: + :maxdepth: 1 + + badges/index + verifiable_credentials/overview diff --git a/docs/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml b/docs/sharing/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml similarity index 100% rename from docs/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml rename to docs/sharing/verifiable_credentials/_puml/verifiable_credentials-issuance-sequence.puml diff --git a/docs/sharing/verifiable_credentials/api_reference.rst b/docs/sharing/verifiable_credentials/api_reference.rst new file mode 100644 index 000000000..83ccdd109 --- /dev/null +++ b/docs/sharing/verifiable_credentials/api_reference.rst @@ -0,0 +1,165 @@ +.. _vc-api-reference: + +API Reference +============= + +All endpoints are prefixed with ``/verifiable_credentials/api/v1/``. + +.. _vc-api-credentials-list: + +GET /credentials/ +----------------- + +List all credentials issued to the authenticated user. Supports filtering by credential type. + +**Authentication:** JWT or Session (required) + +**Query parameters:** + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Parameter + - Type + - Description + * - ``types`` + - string + - Comma-separated credential types to filter. Valid values: ``programcertificate``, ``coursecertificate``. + Omit to return all types. + +**Example request:** + +.. code-block:: sh + + GET /verifiable_credentials/api/v1/credentials/?types=coursecertificate,programcertificate + +**Example response:** + +.. code-block:: json + + { + "program_credentials": [ + { + "uuid": "4a665745d1ba4dfd8f54b58e822b6585", + "status": "awarded", + "username": "staff", + "credential_id": 1, + "credential_uuid": "525756b010aa4c788881141acca72538", + "credential_title": "Title of a program", + "credential_org": "", + "modified_date": "2024-12-18" + } + ], + "course_credentials": [ + { + "uuid": "5135e99ef1d14bca9135972270ef887b", + "status": "awarded", + "username": "staff", + "credential_id": 1, + "credential_uuid": "course-v1:rg+program_course+2024", + "credential_title": "Course cert configuration", + "credential_org": "rg", + "modified_date": "2024-12-18" + } + ] + } + +.. _vc-api-credentials-init: + +POST /credentials/init/ +----------------------- + +Initialize a verifiable credential issuance. Creates an ``IssuanceLine`` and returns a deeplink and QR code for the +learner to complete the flow with their wallet app. + +**Authentication:** JWT or Session (required) + +**Request body:** + +.. list-table:: + :header-rows: 1 + :widths: 25 15 60 + + * - Field + - Type + - Description + * - ``credential_uuid`` + - string (UUID) + - The ``UserCredential`` UUID to issue a VC for. Required. + * - ``storage_id`` + - string + - The storage backend (wallet) identifier. Required. + +**Example response:** + +.. code-block:: json + + { + "deeplink": "dccrequest://request?issuer=did:key:z6Mk...&vc_request_url=...&auth_type=bearer&challenge=...&vp_version=1.1", + "qrcode": "", + "app_link_android": "https://play.google.com/store/apps/details?id=...", + "app_link_ios": "https://apps.apple.com/app/..." + } + +The response includes ``app_link_android`` and ``app_link_ios`` for mobile storage backends, or ``"redirect": true`` +for web-based storage backends. + +.. _vc-api-credentials-issue: + +POST /credentials/issue// +------------------------------- + +Issue a verifiable credential for the given ``IssuanceLine``. The wallet app calls this endpoint after receiving the +deeplink. + +**Authentication:** JWT or Session, **or** a Verifiable Presentation (VP) with ``proofPurpose: "authentication"`` +and a ``challenge`` matching the ``IssuanceLine`` UUID. + +**Returns:** A signed verifiable credential (``201 Created``). + +.. _vc-api-storages: + +GET /storages/ +-------------- + +List all available storage backends (digital wallets). + +**Authentication:** JWT or Session (required) + +**Example response:** + +.. code-block:: json + + [ + { + "id": "credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet", + "name": "Learner Credential Wallet" + } + ] + +.. _vc-api-status-list: + +GET /status-list/2021/v1// +------------------------------------- + +Retrieve the Status List 2021 credential for a given issuer. Relying parties use this endpoint to verify whether a +credential has been revoked. + +**Authentication:** None (public endpoint, ``AllowAny``). + +**Path parameters:** + +.. list-table:: + :header-rows: 1 + :widths: 20 15 65 + + * - Parameter + - Type + - Description + * - ``issuer_id`` + - string + - The issuer's decentralized identifier (DID), e.g. ``did:key:z6Mk...`` + +**Returns:** A signed Status List 2021 verifiable credential. See :ref:`vc-status-list-api` for the full response +structure. diff --git a/docs/verifiable_credentials/components.rst b/docs/sharing/verifiable_credentials/components.rst similarity index 50% rename from docs/verifiable_credentials/components.rst rename to docs/sharing/verifiable_credentials/components.rst index 0fe40e16d..9b3864285 100644 --- a/docs/verifiable_credentials/components.rst +++ b/docs/sharing/verifiable_credentials/components.rst @@ -1,91 +1,128 @@ +.. _vc-components: + Components ========== +The Credentials service contains four main components: **Credentials Core** +manages certificates, **Digital Badges Issuer** handles badge lifecycle with +external platforms, **Verifiable Credentials Issuer** signs W3C credentials, +and the **Learner Record MFE** provides the learner-facing UI. + +.. figure:: ../../_static/images/sharing/credential_sharing_components.png + :alt: C4 Component diagram showing Credentials service internals: Credentials Core, Digital Badges Issuer, Verifiable Credentials Issuer, Learner Record MFE, and their interactions with external systems. + The Verifiable Credentials feature includes the following parts: -- **Verifiable Credentials application** (`credentials.apps.verifiable_credentials` within the Open edX Credentials IDA); -- **Learner Record MFE** (`frontend-app-learner-record` micro-frontend); -- third-party plugins (see `Extensibility`_) -- digital wallets (see `Storages`_) +- **Verifiable Credentials application** (``credentials.apps.verifiable_credentials`` within the Open edX Credentials IDA); +- **Learner Record MFE** (``frontend-app-learner-record`` micro-frontend); +- third-party plugins (see :ref:`vc-extensibility`); +- digital wallets (see :ref:`vc-storages-page`). + +.. _vc-application: Verifiable Credentials application ---------------------------------- -The core backend logic and all related API are encapsulated in the `Verifiable Credentials application`_. +The core backend logic and all related APIs are encapsulated in the `Verifiable Credentials application`_. -Once the Verifiable Credentials feature `is enabled `__: +Once the Verifiable Credentials feature :ref:`is enabled `: 1. Admin site "Verifiable Credentials" section becomes available in the Credentials IDA. -2. Extra urls become available in the Credentials IDA. +2. Extra URLs become available in the Credentials IDA. 3. Extra API endpoints become available within the Credentials IDA. +.. _vc-administration-site: + Administration site ~~~~~~~~~~~~~~~~~~~ -Application section includes: +The application section includes: - a list of available issuers - a list of initiated issuance lines -.. image:: ../_static/images/verifiable_credentials-admin-section.png +.. figure:: ../../_static/images/verifiable_credentials-admin-section.png :alt: Admin section -Currently, only a single Issuer configuration can be active in a moment of time: +Currently, only a single Issuer configuration can be active at a time: -.. image:: ../_static/images/verifiable_credentials-issuer-configuration.png +.. figure:: ../../_static/images/verifiable_credentials-issuer-configuration.png :alt: Issuance Configurations -Issuance configuration describes an Issuer - Organization/University/School on behalf of which verifiable credentials are created. Issuer's ID becomes a part of a verifiable credential and a cryptographic proof is generated with the help of Issuer's private key. Each Issuer has a verbose name. It can be deactivated (checkbox). +An issuance configuration describes an Issuer - the Organization/University/School +on behalf of which verifiable credentials are created. The Issuer's ID is embedded +in each verifiable credential, and a cryptographic proof is generated using the +Issuer's private key. Each Issuer has a display name and can be deactivated via +its checkbox. .. note:: - Private key itself is a secret that is generated with the help of a cryptographic software. - Issuer ID must be a `decentralized identifier`_ created based on a private key. + The private key is a secret generated using cryptographic software. + The Issuer ID must be a `decentralized identifier`_ derived from that private key. Issuance Line - Each request for a verifiable credential issuance initiates a separate Issuance Line. It tracks verifiable credential processing life cycle and keeps a connection with a source Open edX user achievement. + Each request for a verifiable credential initiates a separate Issuance Line. + It tracks the verifiable credential processing lifecycle and maintains a link + to the source Open edX user achievement. -.. image:: ../_static/images/verifiable_credentials-issuance-lines.png +.. figure:: ../../_static/images/verifiable_credentials-issuance-lines.png :alt: Issuance Lines -Issuance line has its unique identifier and additionally includes this information: +Each issuance line has a unique identifier and includes the following information: -1. **User Credential** - related Open edX achievement (e.g. "Program Certificate") -2. **Issuer ID** - issuer's which signs this verifiable credential +1. **User Credential** - related Open edX achievement (e.g. "Program Certificate" or "Course Certificate") +2. **Issuer ID** - issuer which signs this verifiable credential 3. **Storage ID** - a storage backend (digital wallet) which will keep a verifiable credential 4. **Processing status** - if a verifiable credential was successfully uploaded to storage -5. **Status list info** - indicates if a verifiable credential still valid and unique status index within an Issuer's status list +5. **Status list info** - indicates if a verifiable credential is still valid and unique status index within an Issuer's status list +6. **Subject ID** - verifiable credential subject DID +7. **Data model ID** - verifiable credential specification to use +8. **Expiration date** - optional expiration timestamp for the verifiable credential + +.. _vc-learner-record-mfe: Learner Record Microfrontend ------------------------------ +---------------------------- -The Verifiable Credentials feature extends the `Learner Record MFE`_ with additional UI. An extra "Verifiable Credentials" page (tab) becomes available. +The Verifiable Credentials feature extends the `Learner Record MFE`_ with additional +UI. An extra "Verifiable Credentials" page (tab) becomes available. -.. image:: ../_static/images/verifiable_credentials-learner-record-mfe.png +.. figure:: ../../_static/images/verifiable_credentials-learner-record-mfe.png :alt: Verifiable Credentials page -1. Once the Verifiable Credentials feature `is enabled `__ tabs navigation appears -2. All learner's Open edX credentials are listed within the page -3. Achievement card has an action button that allows verifiable credential requesting based on the corresponding Open edX credential -4. Storages options (experimental) +1. Once the Verifiable Credentials feature :ref:`is enabled `, + tab navigation appears. +2. All of the learner's Open edX credentials (both course and program + certificates) are listed on the page. +3. Each achievement card has an action button that lets the learner request a + verifiable credential based on the corresponding Open edX credential. +4. Storage options (experimental). .. note:: - Currently, a single (built-in) storage backend is implemented out of the box (`Learner Credential Wallet`_). In this case the only storage option is available by default, so "Create" action button won't have a dropdown. Additional storages appear under the "Create with" dropdown automatically once configured. + Currently, a single (built-in) storage backend is available out of the box + (`Learner Credential Wallet`_). Because only one storage option exists by + default, the "Create" button does not show a dropdown. Additional storages + appear under a "Create with" dropdown automatically once configured. + +.. _vc-status-list-api: Status List API --------------- -There are a plenty of reasons verifiable credential may be already invalid, inactive or disposed: +There are several reasons a verifiable credential may already be invalid, inactive, or disposed: - revocation - implicit expiration -- a lot of other purposes +- other status changes Open edX maintains status for internal credentials ("awarded", "revoked"). .. note:: Once a Program Certificate X is revoked - **all** verifiable credentials which were issued based on that achievement must become revoked as well. -Public Status List API allows instant verifiable credentials checks. Each issuer maintains its own statuses sequence. Every issued verifiable credential takes a unique position in that sequence. +The public Status List API allows instant verifiable credential checks. This endpoint +is intentionally public (unauthenticated) so that relying parties can verify credential +status without credentials of their own. Each issuer maintains its own status sequence. +Every issued verifiable credential occupies a unique position in that sequence. .. code-block:: sh @@ -161,14 +198,11 @@ Every verifiable credential carries its status list "registration" info. "statusListIndex": "15" }, -Also see related `management command`_ +Also see related :ref:`management command ` .. _Verifiable Credentials application: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials .. _Learner Record MFE: https://github.com/openedx/frontend-app-learner-record -.. _Extensibility: extensibility.html .. _decentralized identifier: https://en.wikipedia.org/wiki/Decentralized_identifier .. _Learner Credential Wallet: https://lcw.app/ -.. _Privacy Considerations: https://w3c.github.io/vc-status-list-2021/#privacy-considerations -.. _management command: configuration.html#status-list-helper -.. _storages: storages.html \ No newline at end of file +.. _Privacy Considerations: https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/#privacy-considerations diff --git a/docs/sharing/verifiable_credentials/composition.rst b/docs/sharing/verifiable_credentials/composition.rst new file mode 100644 index 000000000..31b09f72f --- /dev/null +++ b/docs/sharing/verifiable_credentials/composition.rst @@ -0,0 +1,182 @@ +.. _vc-credential-composition: + +Credential Composition +====================== + +Each verifiable credential is assembled from an ``IssuanceLine`` record and +its related ``UserCredential``. The composition process maps Open edX data +into the structure required by the chosen :ref:`data model `. + +Common fields +------------- + +All data models share these root-level fields: + +.. list-table:: + :header-rows: 1 + :widths: 25 75 + + * - Field + - Source + * - ``id`` + - ``urn:uuid:{IssuanceLine.uuid}`` + * - ``issuer.id`` + - Active ``IssuanceConfiguration`` DID + * - ``issuer.name`` + - Active ``IssuanceConfiguration`` name + * - ``issuanceDate`` / ``issued`` / ``validFrom`` + - ``IssuanceLine.modified`` timestamp + * - ``validUntil`` + - ``IssuanceLine.expiration_date`` (optional) + * - ``credentialStatus`` + - Status List 2021 entry (see :ref:`vc-status-list-api`) + * - ``credentialSubject.id`` + - Subject DID provided by the wallet during issuance + +Subject DID +----------- + +The ``credentialSubject.id`` (the learner's decentralized identifier) is not +generated by Open edX. It is provided by the wallet application during the +issuance request. When the wallet POSTs to the issuance endpoint, the +storage backend's request serializer extracts and validates the subject DID, +then stores it on the ``IssuanceLine``. + +Achievement text generation +--------------------------- + +The ``IssuanceLine`` model builds human-readable text from the underlying +Open edX credential. Three text fields are generated: **name**, +**description**, and **narrative**. Each uses template variables resolved +from the database at issuance time. + +Template variables +~~~~~~~~~~~~~~~~~~ + +.. list-table:: + :header-rows: 1 + :widths: 22 48 30 + + * - Variable + - Source + - Fallback + * - ``credential_type`` + - Mapped from credential class: ``"program certificate"`` or + ``"course certificate"`` + - -- + * - ``program_title`` + - ``Program.title`` + - ``""`` + * - ``course_title`` + - ``Course.title`` (looked up via ``course_id``) + - ``""`` + * - ``organizations`` + - ``Program.authoring_organizations`` names, comma-joined + - ``""`` + * - ``organization`` + - ``course_key.org`` from the course credential + - ``""`` + * - ``platform_name`` + - ``Site.siteconfiguration.platform_name`` + - ``""`` + * - ``recipient_name`` + - ``User.full_name`` (by ``UserCredential.username``) + - ``"recipient"`` + * - ``course_count`` + - ``Program.course_runs.count()`` + - ``0`` + * - ``hours_of_effort`` + - ``Program.total_hours_of_effort`` + - omitted if not set + +Course credential templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Name:** the course's configured title; if absent: ``"Course certificate"``. + +**Description:** + +.. code-block:: text + + {credential_type} is granted on course {course_title} completion + offered by {organization}, in collaboration with {platform_name} + +**Narrative** (placed into the achievement ``criteria`` field): + +.. code-block:: text + + {recipient_name} successfully completed a course and received + a passing grade for a Course Certificate in {course_title} + a course offered by {organization}, in collaboration with + {platform_name}. + +Program credential templates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +**Name:** the program's configured title; if absent, generated as: + +.. code-block:: text + + Program certificate for passing a program {program_title} + +**Description:** + +.. code-block:: text + + {credential_type} is granted on program {program_title} completion + offered by {organizations}, in collaboration with {platform_name}. + The {program_title} program includes {course_count} course(s). + +If ``total_hours_of_effort`` is set, the description appends: + +.. code-block:: text + + , with total {hours_of_effort} Hours of effort required to complete it + +**Narrative** (placed into the achievement ``criteria`` field): + +.. code-block:: text + + {recipient_name} successfully completed all courses and received + passing grades for a Professional Certificate in {program_title} + a program offered by {organizations}, in collaboration with + {platform_name}. + +Data model differences +---------------------- + +.. list-table:: + :header-rows: 1 + :widths: 25 38 37 + + * - Aspect + - Open Badges v3.0 + - VC Data Model v1.1 + * - Extra context + - ``purl.imsglobal.org/.../ob/v3p0`` + - ``schema.org`` + * - Credential type + - ``OpenBadgeCredential`` + - ``EducationalOccupationalCredential`` + * - Subject type + - ``AchievementSubject`` + - (schema.org structures) + * - Achievement + - Nested ``achievement`` object with ``criteria.narrative`` + - ``hasCredential`` relationship + * - Top-level ``name`` + - Yes (credential name) + - No + +Open Badges v3.0.1 extends v3.0 with minor context additions but uses the +same structure. + +Status index assignment +----------------------- + +Each ``IssuanceLine`` receives a monotonically increasing ``status_index`` +scoped to its issuer. The index starts at 0 and increments with each new +issuance. This index determines the credential's position in the issuer's +Status List bitstring. When a credential is revoked, the bit at that index +is flipped to 1 and the Status List is regenerated (gzip-compressed, then +base64url-encoded). diff --git a/docs/sharing/verifiable_credentials/configuration.rst b/docs/sharing/verifiable_credentials/configuration.rst new file mode 100644 index 000000000..9c1f311c4 --- /dev/null +++ b/docs/sharing/verifiable_credentials/configuration.rst @@ -0,0 +1,181 @@ +.. _vc-configuration: + +Configuration +============= + +The Verifiable Credentials feature is optional. It is disabled by default. + +.. _vc-activation: + +Conditional activation +---------------------- + +The ``verifiable_credentials`` app is always in ``INSTALLED_APPS``, but its URL routes, signals, and system checks +only activate when ``ENABLE_VERIFIABLE_CREDENTIALS`` is set to ``True``. After changing this setting, restart the +Credentials service for the change to take effect. + +Learner Record MFE settings +--------------------------- + +The `Learner Record MFE `_ uses environment variables configured in its ``.env`` file: + +``ENABLE_VERIFIABLE_CREDENTIALS`` - enables the verifiable credentials UI routes. + +``SUPPORT_URL_VERIFIABLE_CREDENTIALS`` - footer support link on verifiable credentials pages. + +Credentials service settings +----------------------------- + +``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - main feature flag for the backend. + +The feature introduces its own set of default settings, namespaced under the +``VERIFIABLE_CREDENTIALS`` setting: + +.. code-block:: python + + VERIFIABLE_CREDENTIALS = { + 'DEFAULT_DATA_MODELS': [ + "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", + ], + "STATUS_LIST_LENGTH": 50000, + "DEFAULT_ISSUER": { + "NAME": "The University of the Digital Future", + "KEY": '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}', + "ID": "did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X", + }, + } + +This configuration overrides the corresponding built-in settings: + +1. Data models list narrowed down to a single specification. +2. Status list length extended to 50K positions. +3. Default issuer configured with concrete credentials. + +Default settings +---------------- + +All settings are defined under the ``VERIFIABLE_CREDENTIALS`` dictionary +(see ``verifiable_credentials/settings.py`` for source). + +.. list-table:: + :header-rows: 1 + :widths: 30 70 + + * - Setting + - Description / Default + * - ``DEFAULT_DATA_MODELS`` + - Dotted paths to :ref:`data model ` classes. At least one must be available, and every configured storage must reference an available data model. + + **Default:** ``["credentials.apps.verifiable_credentials.composition.verifiable_credentials.VerifiableCredentialsDataModel", "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel"]`` + * - ``DEFAULT_STORAGES`` + - Dotted paths to :ref:`storage ` classes. At least one must be available. + + **Default:** ``["credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet"]`` + * - ``STATUS_LIST_LENGTH`` + - Per-issuer credential cap. Each issuer has a monotonically increasing status index capped by this value (``unique_together`` constraint). Increase it or create additional issuers to issue more credentials. For details see the `Status List 2021 specification `_. + + **Default:** ``10000`` (16 KB) + * - ``STATUS_LIST_STORAGE`` + - Storage class for the status list implementation. + + **Default:** ``"credentials.apps.verifiable_credentials.storages.status_list.StatusList2021"`` + * - ``STATUS_LIST_DATA_MODEL`` + - Data model class for the status list implementation. + + **Default:** ``"credentials.apps.verifiable_credentials.composition.status_list.StatusListDataModel"`` + * - ``DEFAULT_ISSUANCE_REQUEST_SERIALIZER`` + - Serializer for incoming issuance requests. + + **Default:** ``"credentials.apps.verifiable_credentials.issuance.serializers.IssuanceLineSerializer"`` + * - ``DEFAULT_RENDERER`` + - Renderer for outgoing verifiable credential responses. + + **Default:** ``"credentials.apps.verifiable_credentials.issuance.renderers.JSONLDRenderer"`` + +DEFAULT_ISSUER +~~~~~~~~~~~~~~ + +Issuer identity used during the first deployment data migration. +Multiple ``IssuanceConfiguration`` records can exist in the database, but +only the last enabled record is the active issuer for all verifiable +credentials. + +.. important:: + The admin interface prevents disabling the last enabled configuration. + Use ``remove_issuance_configuration`` to delete one entirely. + +.. list-table:: + :header-rows: 1 + :widths: 20 80 + + * - Key + - Description / Default + * - ``NAME`` + - Verbose issuer name embedded in each verifiable credential. + + **Default:** ``"Default (system-wide)"`` + * - ``KEY`` + - Private JWK used for signing. Use your own key or generate one with the ``generate_issuer_credentials`` command below. + + **Default:** placeholder (must be replaced) + * - ``ID`` + - Decentralized Identifier (DID) derived from the private key. + + **Default:** placeholder (must be replaced) + +.. _vc-management-commands: + +Management commands +------------------- + +All commands below run in the **Credentials service**. + +.. _vc-issuer-credentials-helper: + +``generate_issuer_credentials`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Generates a new private key (JWK) and a decentralized identifier (DID) for an +issuer. + +.. code-block:: sh + + ./manage.py generate_issuer_credentials + >> { + 'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', + 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}' + } + +``create_default_issuer`` +~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates an Issuance Configuration from ``VERIFIABLE_CREDENTIALS[DEFAULT_ISSUER]`` +settings. A default configuration is created automatically during the first +deployment via data migration. Use this command to re-create it if needed. + +.. code-block:: sh + + ./manage.py create_default_issuer + +``remove_issuance_configuration`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Removes an issuer configuration by its DID. The admin interface only allows +deactivation, not deletion. + +.. code-block:: sh + + ./manage.py remove_issuance_configuration did:key: + +.. _vc-status-list-helper: + +``generate_status_list`` +~~~~~~~~~~~~~~~~~~~~~~~~ + +Generates a signed Status List 2021 credential for a given issuer. Useful for +debugging revocation status or verifying the status list is correctly formed. + +.. code-block:: sh + + ./manage.py generate_status_list did:key: + diff --git a/docs/sharing/verifiable_credentials/extensibility.rst b/docs/sharing/verifiable_credentials/extensibility.rst new file mode 100644 index 000000000..510997133 --- /dev/null +++ b/docs/sharing/verifiable_credentials/extensibility.rst @@ -0,0 +1,67 @@ +.. _vc-extensibility: + +Extensibility +============= + +Both :ref:`data models ` and :ref:`storages ` may be implemented as installable pluggable applications for the Credentials IDA. + +.. _vc-storages: + +Storages +-------- + +Storage backend classes describe a destination for issued verifiable credentials. +Storages represent wallet integrations (mobile or web applications). + +See available options on the :ref:`Storages page `. + +.. note:: + + For a storage plugin example, see the `openedx-wallet`_ dummy internal storage (by `Raccoon Gang`_). + +.. _vc-data-models: + +Data Models +----------- + +Data model classes are `DRF`_ serializers that compose verifiable credentials +according to different specifications. + +Credentials data models +~~~~~~~~~~~~~~~~~~~~~~~ + +There are 3 specifications included by default: + +- `Open Badges Specification v3.0`_ (see `OB3.0 model`_) +- `Open Badges Specification v3.0.1`_ (see `OB3.0.1 model`_) +- `Verifiable Credentials Data Model v1.1`_ (see `VC1.1 model`_) - experimental + +Additional specifications may be implemented as separate plugins. + +Credentials status information +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +:ref:`Status List v2021 ` is a special kind of verifiable +credential. It serves as a verification mechanism for issued verifiable +credentials (meaning, it does not carry achievement information itself but +acts as a registry of statuses for all created achievement-related verifiable +credentials). Status information allows instant checks to determine whether +a presented verifiable credential is still valid. The credential issuer can +invalidate a verifiable credential by updating its indexed record in the +status list. + +See full specification in the `Verifiable Credential Status List v2021`_ community report. + + + +.. _Verifiable Credentials Data Model v1.1: https://www.w3.org/TR/vc-data-model-1.1/ +.. _Open Badges Specification v3.0: https://1edtech.github.io/openbadges-specification/ob_v3p0.html +.. _Open Badges Specification v3.0.1: https://www.imsglobal.org/spec/ob/v3p0/impl/ +.. _Verifiable Credential Status List v2021: https://www.w3.org/community/reports/credentials/CG-FINAL-vc-status-list-2021-20230102/ +.. _Raccoon Gang: https://raccoongang.com +.. _Learner Credential Wallet: https://lcw.app +.. _DRF: https://www.django-rest-framework.org/ +.. _VC1.1 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/verifiable_credentials.py +.. _OB3.0 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/open_badges.py +.. _OB3.0.1 model: https://github.com/openedx/credentials/blob/master/credentials/apps/verifiable_credentials/composition/open_badges.py +.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet diff --git a/docs/sharing/verifiable_credentials/overview.rst b/docs/sharing/verifiable_credentials/overview.rst new file mode 100644 index 000000000..5029f7767 --- /dev/null +++ b/docs/sharing/verifiable_credentials/overview.rst @@ -0,0 +1,113 @@ +Verifiable Credentials +====================== + +Traditional certificates (PDFs, images) are easy to forge and hard to verify. +Employers and institutions that receive them must contact the issuing organization +to confirm authenticity - a slow, manual process that doesn't scale. + +`Verifiable Credentials`_ (VCs) solve this problem. A VC is a digitally signed, +tamper-proof data object that any party can verify instantly, without contacting +the issuer. The `W3C Verifiable Credentials Data Model`_ and related +specifications define the standard. + +Credentials ecosystem +--------------------- + +Three roles participate in the learner credentials ecosystem: + +- **Learner** - holds portable, privacy-preserving proof of achievements + in a digital wallet and shares them with employers, institutions, or + professional networks. +- **Issuer** - creates and signs credentials. The cryptographic signature + ties each credential back to the issuing organization, making + authenticity independently verifiable. +- **Verifier** - validates a credential's signature and revocation status + without contacting the issuer directly, using a public + :ref:`Status List `. + + +Verifiable credentials lifecycle +-------------------------------- + +The W3C VC specification defines a standard lifecycle with three participants: + +- **Issuer** (``did:web:domain.university.org``) - creates and signs + verifiable credentials, can revoke them. +- **Holder** (``did:key:[unique-id]``) - receives, stores, and transfers + VCs. Presents a VC or a Verifiable Presentation (VP) to verifiers. +- **Verifier** - checks the credential's signature and consults a + Verifiable Data Registry (e.g. the issuer's Status List) to confirm the + credential has not been revoked or expired. + +.. figure:: ../../_static/images/sharing/vc_lifecycle.png + :alt: Verifiable credentials lifecycle diagram showing Issuer, Holders, and Verifiers interacting through Issue VC, Transfer, Present VC or VP, Check Status, Revoke VC, and Verify flows via a Verifiable Data Registry. + +Decentralized identifiers (DIDs) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Both issuers and holders are identified by +`Decentralized Identifiers (DIDs) `_. +A DID follows the format ``did:[method]:[unique-uri]``. Common methods include: + +- ``did:key`` - self-contained, no external resolution needed. Used for learner (holder) identifiers. +- ``did:web`` - resolved via the issuer's domain over HTTPS. Used for institutional issuers. +- ``did:ethr`` - resolved via Ethereum blockchain. + +A DID resolves to a **DID Document** containing the public key material needed to verify signatures. + +How It Works in Open edX +------------------------ + +The Verifiable Credentials feature is optional. Once enabled, it extends the +Credentials service and Learner Record micro-frontend. + +A single Open edX achievement can be used as a source for multiple verifiable +credentials, each using a different data model if needed. The typical flow +looks like this. + +#. A learner earns an Open edX credential (course or program certificate). +#. The learner visits the Learner Record page and requests a verifiable + credential. The platform generates a deep link or QR code. +#. The learner scans the QR code or follows the deep link to open their + digital wallet app. +#. The digital wallet sends an issuance request back to the platform. The + platform signs the credential using the configured issuer's private key + and returns it to the wallet. +#. The learner can now present the VC to any relying party. +#. The relying party verifies the signature and checks the issuer's public + status list to confirm the credential is still valid (not expired or + revoked). + +Setup +----- + +Setting up VCs involves a few steps. + +#. Enable the feature flag (``ENABLE_VERIFIABLE_CREDENTIALS``). +#. Generate issuer credentials (a decentralized identifier and private key). +#. Configure the issuer in the Credentials admin site. +#. Ensure the Status List API endpoint is publicly accessible. + +See the :ref:`Quick Start ` guide for detailed instructions. + +The feature supports multiple verifiable credential specifications +(Open Badges v3.0, v3.0.1, and the W3C VC Data Model v1.1) and multiple +digital wallet backends. Both can be extended through plugins - see +:ref:`vc-extensibility` for details. + +---- + +.. toctree:: + :maxdepth: 1 + + quickstart + components + configuration + extensibility + composition + storages + tech_details + api_reference + +.. _Verifiable Credentials: https://en.wikipedia.org/wiki/Verifiable_credentials +.. _W3C Verifiable Credentials Data Model: https://www.w3.org/TR/vc-data-model-1.1/ diff --git a/docs/sharing/verifiable_credentials/quickstart.rst b/docs/sharing/verifiable_credentials/quickstart.rst new file mode 100644 index 000000000..1314d3e69 --- /dev/null +++ b/docs/sharing/verifiable_credentials/quickstart.rst @@ -0,0 +1,92 @@ +.. _vc-quickstart: + +Quick Start +=========== + +.. contents:: Steps + :local: + :class: no-bullets + +This guide walks through the initial setup for the Verifiable Credentials +feature. + +1. Feature activation +--------------------- + +The Verifiable Credentials feature is optional and must be explicitly enabled. + +.. code:: + + # both Credentials service and Learner Record MFE: + ENABLE_VERIFIABLE_CREDENTIALS = true + +See :ref:`vc-configuration` for more details. + +2. Issuer credentials generation +-------------------------------- + +Once enabled, the Verifiable Credentials feature has reasonable defaults. The +only additional step needed is the issuer_ credentials setup. Unless you +already have an appropriate issuer key and issuer ID, you need to generate +them: + +.. code-block:: sh + + # Run in the Credentials service: + ./manage.py generate_issuer_credentials + >> { + 'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', + 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL"}' + } + +Here: + + - "did" - unique Issuer decentralized identifier + - "private_key" - Issuer private JWK + +See :ref:`vc-management-commands` for more details. + +3. Issuer credentials setup +--------------------------- + +Use the generated credentials to replace the stub values in the auto-created +Issuance Configuration. + +Open the Credentials Administration interface and find the "VERIFIABLE +CREDENTIALS" section +(``/admin/verifiable_credentials/issuanceconfiguration/``). + +.. code:: + + Issuer id: use "did" + Issuer key: use "private_key" + Issuer name: will be used as issuer's verbose name + +.. note:: + :class: dropdown + + Make sure the configuration is enabled. + +See :ref:`vc-administration-site` for more details. + +4. Ensure status list is accessible +----------------------------------- + +The Status List API endpoint is crucial for the feature. Once everything is +configured correctly, it must be publicly available: + +.. code:: + + # each Issuer maintains its own Status List: + https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1// + +See :ref:`vc-status-list-api` for more details. + +5. Issuer registration (Learner Credential Wallet) +-------------------------------------------------- + +This step is specific for the Learner Credential Wallet storage. + +See Learner Credential Wallet :ref:`usage prerequisites `. + +.. _issuer: https://www.w3.org/TR/vc-data-model-1.1/#dfn-issuers diff --git a/docs/verifiable_credentials/storages.rst b/docs/sharing/verifiable_credentials/storages.rst similarity index 52% rename from docs/verifiable_credentials/storages.rst rename to docs/sharing/verifiable_credentials/storages.rst index 83f202b5d..7efebd56a 100644 --- a/docs/verifiable_credentials/storages.rst +++ b/docs/sharing/verifiable_credentials/storages.rst @@ -1,86 +1,139 @@ +.. _vc-storages-page: + Storages ======== -Currently there is the only digital wallet is supported for production. +Currently, only one digital wallet is supported for production. Learner Credential Wallet ------------------------- -`Official web-site`_: +`Official website`_: + + Learner Credential Wallet is an open source mobile wallet developed by the + Digital Credentials Consortium, a network of leading international + universities designing an open infrastructure for academic credentials. - Learner Credential Wallet is an open source mobile wallet developed by the Digital Credentials Consortium, a network of leading international universities designing an open infrastructure for academic credentials. +Learner Credential Wallet (LCWallet) is a mobile app available for Android +and iOS devices. -Learner Credential Wallet (LCWallet) is a mobile app available for Android and IOS devices. +.. _vc-usage-prerequisites: Usage prerequisites ~~~~~~~~~~~~~~~~~~~ -LCWallet maintainer (`Digital Credentials Consortium`_) requires verifiable credentials issuer to be allow-listed (included to the trusted issuers list - `community issuer registry`_). +The LCWallet maintainer (`Digital Credentials Consortium`_) requires the +verifiable credentials issuer to be allow-listed (included in the trusted +issuers list - `community issuer registry`_). .. note:: - For development/testing purposes a `Sandbox Registry`_ is available. If you would like to be added to the Sandbox Registry, please open a pull requests directly against that repository, matching the format for existing issuers in `registry.json` + For development/testing purposes a `Sandbox Registry`_ is available. If + you would like to be added to the Sandbox Registry, please open a pull + request directly against that repository, matching the format for existing + issuers in ``registry.json``. Learner experience ~~~~~~~~~~~~~~~~~~ -This explains a generic usage flow for learners. +This explains the generic usage flow for learners. -#. Learners have to download and install the official application (Google Play or App Store, we'll use Android version for examples). +#. Learners download and install the official application (Google Play or App + Store; the Android version is used for examples below). -#. Once installed there is initial one-time setup guide. +#. Once installed, there is an initial one-time setup guide. - .. image:: ../_static/images/verifiable_credentials-lcw-setup1.png + .. image:: ../../_static/images/verifiable_credentials-lcw-setup1.png :alt: Learner Credential Wallet setup step 1 :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-setup2.png + .. image:: ../../_static/images/verifiable_credentials-lcw-setup2.png :alt: Learner Credential Wallet setup step 2 :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-setup3.png + .. image:: ../../_static/images/verifiable_credentials-lcw-setup3.png :alt: Learner Credential Wallet setup step 3 :width: 30% -#. Learners navigate Learner Record MFE interface (`Verifiable Credentials tab`_) and claim for a verifiable credential issuance (clicking a :guilabel:`Create` button). +#. Learners navigate to the Learner Record MFE interface + (:ref:`Verifiable Credentials tab `) and request a + verifiable credential by clicking the :guilabel:`Create` button. -#. On the next step learners are asked for QR code scanning - that's where the LCWallet app starts its flow. Learners use :guilabel:`Scan QR code` option in the mobile application. +#. Learners are then asked to scan a QR code - this is where the LCWallet app + starts its flow. Learners use the :guilabel:`Scan QR code` option in the + mobile application. - .. image:: ../_static/images/verifiable_credentials-lcw-home-empty.png + .. image:: ../../_static/images/verifiable_credentials-lcw-home-empty.png :alt: Learner Credential Wallet empty :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-add-credential.png + .. image:: ../../_static/images/verifiable_credentials-lcw-add-credential.png :alt: Learner Credential Wallet add credential :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-qrcode-scanner.png + .. image:: ../../_static/images/verifiable_credentials-lcw-qrcode-scanner.png :alt: Learner Credential Wallet QR code scanner :width: 30% -#. LCWallet processes QR code, communicates with the Open edX Platform and gets new verifiable credential. If everything is correct, now digital wallet holds the verifiable credential for the given Open edX credential (program certificate). +#. LCWallet processes the QR code, communicates with the Open edX platform, + and retrieves the new verifiable credential. If everything is correct, the + digital wallet now holds the verifiable credential for the given Open edX + credential (course or program certificate). - .. image:: ../_static/images/verifiable_credentials-lcw-accept-credential.png + .. image:: ../../_static/images/verifiable_credentials-lcw-accept-credential.png :alt: Learner Credential Wallet accept credential :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-credential-preview.png + .. image:: ../../_static/images/verifiable_credentials-lcw-credential-preview.png :alt: Learner Credential Wallet credential preview :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-verification-status.png + .. image:: ../../_static/images/verifiable_credentials-lcw-verification-status.png :alt: Learner Credential Wallet credential status :width: 30% -#. From this point learners are free to share their achievements in different ways +#. From this point, learners are free to share their achievements in different + ways. - .. image:: ../_static/images/verifiable_credentials-lcw-share.png + .. image:: ../../_static/images/verifiable_credentials-lcw-share.png :alt: Learner Credential Wallet share credential :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-share-public-link.png + .. image:: ../../_static/images/verifiable_credentials-lcw-share-public-link.png :alt: Learner Credential Wallet share credential with public link :width: 30% - .. image:: ../_static/images/verifiable_credentials-lcw-share-public-link-created.png + .. image:: ../../_static/images/verifiable_credentials-lcw-share-public-link-created.png :alt: Learner Credential Wallet shared with public link credential :width: 30% +.. _vc-wallet-deeplink-protocol: + +Deeplink protocol +~~~~~~~~~~~~~~~~~ + +The LCWallet storage backend constructs deeplinks using the ``dccrequest://`` +scheme. The full deeplink format is: + +.. code-block:: text + + dccrequest://request?issuer={id}&vc_request_url={url}&auth_type=bearer&challenge={uuid}&vp_version=1.1 + +The end-to-end flow works as follows. + +#. The learner clicks :guilabel:`Create` in the Learner Record MFE. +#. The backend creates an ``IssuanceLine`` and returns a deeplink URL and + QR code. +#. The learner scans the QR code or clicks the deeplink, which opens the + wallet app. +#. The wallet constructs a Verifiable Presentation (VP) using the + ``challenge`` parameter as proof of authorization. +#. The wallet POSTs the VP to ``/credentials/issue//``. +#. The backend verifies the VP, signs the credential, and returns it to + the wallet. + +.. note:: + The issuance endpoint accepts dual authentication: standard JWT/Session + auth or a Verifiable Presentation with + ``proofPurpose: "authentication"`` and a ``challenge`` matching the + ``IssuanceLine.uuid``. The VP signature is verified via ``didkit``. + +Example verifiable presentation: + .. code:: - # an example of a verifiable presentation being shared: { "@context": [ "https://www.w3.org/2018/credentials/v1" @@ -142,14 +195,15 @@ This explains a generic usage flow for learners. ] } -Other options -------------- +Development wallet +------------------ -Additionally, you can install the `openedx-wallet`_ POC for investigation/onboarding purposes. This wallet is not recommended for production deployment. +The `openedx-wallet`_ is a proof-of-concept wallet for +investigation and onboarding purposes. It is not recommended for +production deployment. -.. _Official web-site: https://lcw.app/ +.. _Official website: https://lcw.app/ .. _Digital Credentials Consortium: https://digitalcredentials.mit.edu/ .. _community issuer registry: https://github.com/digitalcredentials/community-registry .. _`Sandbox Registry`: https://github.com/digitalcredentials/sandbox-registry -.. _`Verifiable Credentials tab`: components.html#learner-record-microfrontend -.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet \ No newline at end of file +.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet diff --git a/docs/sharing/verifiable_credentials/tech_details.rst b/docs/sharing/verifiable_credentials/tech_details.rst new file mode 100644 index 000000000..5e52c2d89 --- /dev/null +++ b/docs/sharing/verifiable_credentials/tech_details.rst @@ -0,0 +1,107 @@ +.. _vc-tech-details: + +Implementation Details +====================== + +This section covers internal details that may help with debugging, +customization, or deeper understanding of the feature. + +Prerequisites +------------- + +The following conditions must be met before verifiable credentials can be +issued. + +1. The ``verifiable_credentials`` app does not register its URL configuration + or admin views until the main feature flag is enabled. +2. The default built-in configuration is almost self-contained - the only + required step is to configure the Issuer's credentials (see + :ref:`management command helper `). If the + Issuer is configured in the deployment environment from the start, those + settings are used during the app data migration; otherwise, a manual + Issuance Configuration edit is needed (Credentials admin site). +3. Multiple Issuance Configuration records can exist, but only the last + enabled record is used. + +Events flow +----------- + +The following diagram illustrates the end-to-end issuance sequence. + +.. figure:: ../../_static/images/verifiable_credentials-issuance-sequence.png + :alt: Verifiable Credentials issuance sequence diagram + +- 1 - Learner navigates to the Learner Record MFE, enters the Verifiable Credentials page. +- 2,3 - Frontend fetches all Learner's credentials (program certificates). +- 4,5 - Frontend fetches configured storages list. +- Learner chooses their credential (program certificate) to issue verifiable credential for. +- 6,7 - Learner initiates an issuance (standard case: single storage, experimental case: many storages). +- 8 - Issuance Line is created with given context (storage + program certificate). +- 9 - all pre-requisites are evaluated and deep-link/QR code generated. +- Learner sees a modal dialog with deep-link/QR code to proceed with a mobile wallet app. +- 10,11 - Learner interacts with a dialog data (clicks/scans). +- 12 - Learner navigates to a mobile wallet app. +- 13 - mobile wallet app requests verifiable credential from an issuance API endpoint (on behalf of a Learner). +- verifiable_credentials application processes Issuance Line data (collects required data, composes it into a desired shape, evaluates status list data, adds signature). +- 14 - well-formed verifiable credential returned to a mobile wallet app. +- Mobile app verifies given verifiable credential (validates structure, signature, status info). + +Credential signing +------------------ + +All credentials are signed using the **Ed25519Signature2020** proof suite exclusively. + +VP authentication +----------------- + +The ``IssueCredentialView`` accepts dual authentication: standard JWT/Session auth **or** a Verifiable Presentation +with ``proofPurpose: "authentication"`` and a ``challenge`` matching the ``IssuanceLine.uuid``. The VP signature is +verified via ``didkit``. + +Signal-based status sync +------------------------ + +When a ``UserCredential`` status changes (e.g. revocation), all related ``IssuanceLine`` records are automatically +updated via a Django ``post_save`` signal. This ensures verifiable credentials reflect the current status of the +underlying Open edX achievement. In the case of revocation, the updated status is reflected in the issuer's +:ref:`Status List `, allowing relying parties to detect revoked credentials during +verification. + +Synchronous didkit operations +----------------------------- + +All ``didkit`` cryptographic operations are async functions wrapped with ``async_to_sync``. Each issuance blocks a +Django worker thread during signing. Consider this when sizing your deployment for high-volume issuance. + +Technology choices +------------------ + +openedx-didkit +~~~~~~~~~~~~~~ + +The cryptographic core is `openedx-didkit`_, a fork of the original `DidKit`_ library by SpruceID with added +Verifiable Credentials v2 support. It is Rust-based and integrated into Python via PyO3 bindings. + +.. _openedx-didkit: https://github.com/openedx/openedx-didkit +.. _DidKit: https://github.com/spruceid/didkit + +Status List 2021 +~~~~~~~~~~~~~~~~ + +Revocation tracking uses the `Status List 2021`_ specification - a simple bitstring where each issued +credential occupies one bit position. This approach was chosen over blockchain-based solutions for its +simplicity and because the status list is served as a standard API endpoint from the Credentials service +(see :ref:`vc-status-list-api`). + +.. _Status List 2021: https://www.w3.org/TR/2023/WD-vc-status-list-20230427/ + +OpenBadges v3.0 +~~~~~~~~~~~~~~~ + +The default data model is `Open Badges v3.0`_, a specification designed specifically for educational +achievements. It aligns with both VC Data Model v1.1 and v2.0, making credentials interoperable with +the broader verifiable credentials ecosystem while retaining education-specific semantics (achievements, +criteria, evidence). + +.. _Open Badges v3.0: https://www.imsglobal.org/spec/ob/v3p0/ + diff --git a/docs/verifiable_credentials/configuration.rst b/docs/verifiable_credentials/configuration.rst deleted file mode 100644 index 7f2c615a5..000000000 --- a/docs/verifiable_credentials/configuration.rst +++ /dev/null @@ -1,192 +0,0 @@ -Configuration -============= - -Verifiable Credentials feature is optional. It is disabled by default. - -Learner Record micro-frontend ------------------------------ - -The most of configuration is related to the Credentials IDA (`verifiable_credentials` app), but there are few UI-related settings. - -``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - enables feature appearance (extra routes) - -``SUPPORT_URL_VERIFIABLE_CREDENTIALS`` (URL string) - footer support link - -Verifiable Credentials application ----------------------------------- - -``ENABLE_VERIFIABLE_CREDENTIALS`` (boolean) - main feature flag - -The feature introduces its own set of default settings which are namespaced in the VERIFIABLE_CREDENTIALS setting, like this: - -.. code-block:: python - - VERIFIABLE_CREDENTIALS = { - 'DEFAULT_DATA_MODELS': [ - "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", - ], - "STATUS_LIST_LENGTH": 50000, - "DEFAULT_ISSUER": { - "NAME": "The University of the Digital Future", - "KEY": '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}', - "ID": "did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X", - }, - } - -Such configuration overrides the corresponding built-in settings: - -1. Data models list narrowed down to a single specification -2. Status list length extended to 50K positions -3. Default issuer configured with concrete credentials - -Built-in values ---------------- - -There is a set of built-in predefined settings: - -.. code-block:: python - - # verifiable_credentials/settings.py - - DEFAULTS = { - "DEFAULT_DATA_MODELS": [ - "credentials.apps.verifiable_credentials.composition.verifiable_credentials.VerifiableCredentialsDataModel", - "credentials.apps.verifiable_credentials.composition.open_badges.OpenBadgesDataModel", - ], - "DEFAULT_STORAGES": [ - "credentials.apps.verifiable_credentials.storages.learner_credential_wallet.LCWallet", - ], - "DEFAULT_ISSUER": { - "ID": "generate-me-with-didkit-lib", - "KEY": "generate-me-with-didkit-lib", - "NAME": "Default (system-wide)", - }, - "DEFAULT_ISSUANCE_REQUEST_SERIALIZER": "credentials.apps.verifiable_credentials.issuance.serializers.IssuanceLineSerializer", - "DEFAULT_RENDERER": "credentials.apps.verifiable_credentials.issuance.renderers.JSONLDRenderer", - "STATUS_LIST_STORAGE": "credentials.apps.verifiable_credentials.storages.status_list.StatusList2021", - "STATUS_LIST_DATA_MODEL": "credentials.apps.verifiable_credentials.composition.status_list.StatusListDataModel", - "STATUS_LIST_LENGTH": 10000, - } - -Default data models -------------------- - -Deployment configuration can override `data models set`_ with the respect of the following restrictions: - -- there always must be at least 1 data model available -- each storage is pre-configured to use some data model which must be available - -Default storages ----------------- - -Deployment configuration can override `storages set`_ with the respect of the following restrictions: - -- there always must be at least 1 storage available - - -Default issuer --------------- - -.. note:: - Currently, there is only a single active issuer (system-wide) available So, all verifiable credentials are created (issued) on behalf of this Issuer. - -There is the `Issuance Configuration`_ database model, which initial record is created based on these settings. - -NAME -~~~~ - -Verbose issuer name (it is placed into each verifiable credential). - -KEY -~~~ - -A private secret key (JWK) which is used for verifiable credentials issuance (proof/digital signature generation). It can be generated with the help of the `didkit`_ Python (Rust) library. - -ID -~~ - -A unique issuer decentralized identifier (created from a private key, `example`_). - -Status List configuration -------------------------- - -Length -~~~~~~ - -``STATUS_LIST_LENGTH`` - default = 10000 (16KB) - -Possibly, the only status list settings to configure. A status sequence positions count (how many issued verifiable credentials statuses are included). See `related specs`_ for details. - -Storage -~~~~~~~ - -``STATUS_LIST_STORAGE`` - -A technical storage class (allows status list implementation override). - -Data model -~~~~~~~~~~ - -``STATUS_LIST_DATA_MODEL`` - -A data model class (allows status list implementation override). - ----- - -Other settings are available for advanced tweaks but usually are not meant to be configured: - -- Default issuance request serializer (incoming issuance request parsing) -- Default renderer (outgoing verifiable credential presentation) - -Management commands -------------------- - -There are a couple of service commands available for the verifiable_credentials application. - -Issuer credentials helper -~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Generates private key for Issuer (JWK) and a decentralized identifier (DID) based on that key.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_issuer_credentials - >> {'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', - 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL-hg"}'} - -Issuer configuration helpers -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -**Create initial Issuance Configuration based on deployment issuer(s) setup.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py create_default_issuer - -Initial Issuance configuration is created based on VERIFIABLE_CREDENTIALS[DEFAULT_ISSUER] via data migration during the first deployment. Helper allows manually repeat that is needed (Additional configurations can be created from django admin interface). - -**Remove Issuance Configuration based on Issuer ID.** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py remove_issuance_configuration did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X - -Issuance configuration delete operation is forbidden in admin interface (only deactivation is available). This tool allows to cleanup configurations list if needed. - -Status List helper -~~~~~~~~~~~~~~~~~~ - -**Generate Status List 2021 verifiable credential** - -.. code-block:: sh - - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_status_list did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X - -Allows Status List verifiable credential generation (for a given Issuer ID). - -.. _data models set: extensibility.html#data-models -.. _storages set: extensibility.html#storages -.. _didkit: https://pypi.org/project/didkit/ -.. _example: https://github.com/spruceid/didkit-python/blob/main/examples/python_django/didkit_django/issue_credential.py#L12 -.. _related specs : https://w3c.github.io/vc-status-list-2021/#revocation-bitstring-length -.. _Issuance Configuration: components.html#administration-site \ No newline at end of file diff --git a/docs/verifiable_credentials/extensibility.rst b/docs/verifiable_credentials/extensibility.rst deleted file mode 100644 index 9c1c2dc96..000000000 --- a/docs/verifiable_credentials/extensibility.rst +++ /dev/null @@ -1,64 +0,0 @@ -Extensibility -============= - -Storages --------- - -Storage backend classes describe a destination for issued verifiable credentials. Basically, storages are wallets (mobile or web applications). - -See available options on `Storages page`_. - -Data Models ------------ - -Data model classes are `DRF`_ serializers which compose verifiable credentials of different specifications. - -Credentials data models -~~~~~~~~~~~~~~~~~~~~~~~ - -There are 2 specifications included by default: - -- `Open Badges Specification v3.0`_ (see `OB3.0 model`_) -- `Verifiable Credentials Data Model v1.1`_ (see `VC1.1 model`_) - experimental - -Additional specifications may be implemented as separate `plugins`_. - -Credentials status information -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -.. note:: - - Status information allows instant checks to figure out if the presented verifiable credential is still valid. The credential issuer can invalidate a verifiable credential by updating its indexed record in the status list. - -`Status List v2021`_ is a special kind of verifiable credential. It serves as a mechanism of verification for issued verifiable credentials (meaning, it does not carry achievement information itself but it is a registry of statuses for all created achievement-related verifiable credentials). - -- `Verifiable Credential Status List v2021`_ - -There are 2 parts of the approach: - -- status entry (becomes a part of each issued verifiable credential and carries the info "how to check status") -- status list (an Issuer-centric separate freely reachable statuses registry) - -Plugins -------- - -Both `data models`_ and `storages`_ may be implemented as Credentials IDA installable pluggable applications. - -.. note:: - - For storage plugin example, please, see the `openedx-wallet`_ training storage (by the `Raccoon Gang`_) . - -.. _Verifiable Credentials Data Model v1.1: https://www.w3.org/TR/vc-data-model-1.1/ -.. _Open Badges Specification v3.0: https://1edtech.github.io/openbadges-specification/ob_v3p0.html -.. _Verifiable Credential Status List v2021: https://w3c.github.io/vc-status-list-2021/ -.. _data models: extensibility.html#data-models -.. _storages: extensibility.html#storages -.. _storages page: storages.html -.. _plugins: extensibility.html#plugins -.. _Raccoon Gang : https://raccoongang.com -.. _Learner Credential Wallet: https://lcw.app -.. _DRF: https://www.django-rest-framework.org/ -.. _Status List v2021: components.html#status-list-api -.. _VC1.1 model: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials/composition/verifiable_credentials.py -.. _OB3.0 model: https://github.com/openedx/credentials/tree/master/credentials/apps/verifiable_credentials/composition/open_badges.py -.. _openedx-wallet: https://github.com/raccoongang/openedx-wallet \ No newline at end of file diff --git a/docs/verifiable_credentials/overview.rst b/docs/verifiable_credentials/overview.rst deleted file mode 100644 index b13182be8..000000000 --- a/docs/verifiable_credentials/overview.rst +++ /dev/null @@ -1,27 +0,0 @@ -Verifiable Credentials -====================== - -An optional feature that allows issuance of the `Verifiable Credentials`_ based on the Open edX achievements. - - *Verifiable credentials will allows us to represent our achievements in a provable, portable, sharable, privacy and autonomy preserving way.* - -Please, see `Extensibility`_ section for the list of supported: - -- verifiable credential specifications (data models) -- digital wallets (storages) - ----- - -.. toctree:: - :maxdepth: 1 - - quickstart - usage - components - configuration - extensibility - storages - tech_details - -.. _Verifiable Credentials: https://en.wikipedia.org/wiki/Verifiable_credentials -.. _Extensibility: extensibility.html \ No newline at end of file diff --git a/docs/verifiable_credentials/quickstart.rst b/docs/verifiable_credentials/quickstart.rst deleted file mode 100644 index 0755e9e53..000000000 --- a/docs/verifiable_credentials/quickstart.rst +++ /dev/null @@ -1,87 +0,0 @@ -Quick Start -=================================== - -.. contents:: Steps - :local: - :class: no-bullets - -This guide outlines initial preparations for the Verifiable Credentials feature. - -1. Feature activation ---------------------- - -Since Verifiable Credentials feature is optional, it must be enabled to be accessible. - -.. code:: - - # both Credentials service and Learner Record MFE: - ENABLE_VERIFIABLE_CREDENTIALS = true - -See Configuration_ for more details. - -2. Issuer credentials generation --------------------------------- - -Once enabled Verifiable Credentials feature has reasonable defaults. The only additional activity is needed - issuer_ credentials setup. Unless we already have appropriate issuer key and issuer ID, we have to generate those: - -.. code:: - - # use management command: - root@credentials:/edx/app/credentials/credentials# ./manage.py generate_issuer_credentials - >> { - 'did': 'did:key:z6MkgdiV7pVPCapM8oUwfhxBwYZgh8dXkHkJykSAc4DHKD7X', - 'private_key': '{"kty":"OKP","crv":"Ed25519","x":"IGUT8E_aRNzLqouWO4zdeZ6l4CEXsVmJDOpOQS69m7o","d":"vn8xgdO5Ki3zlvRNc2nUqcj50Ise1Vl1tlbs9DUL"}' - } - -Here: - - - "did" - unique Issuer decentralized identifier - - "private_key" - Issuer private JWK - -See `Management commands`_ for more details. - -3. Issuer credentials setup ---------------------------- - -Generated issuer credentials we'll use to update automatically generated with stub values Issuance Configuration. - -Enter Credentials Administration interface and find "VERIFIABLE CREDENTIALS" section (`/admin/verifiable_credentials/issuanceconfiguration/`). - -.. code:: - - Issuer id: use "did" - Issuer key: use "private_key" - Issuer name: will be used as issuer's verbose name - -.. note:: - :class: dropdown - - Make sure the configuration is enabled. - -See `Administration site`_ for more details. - -4. Ensure status list is accessible ------------------------------------ - -Status List API endpoint is crucial for the feature. Once everything is configured correctly it must be publicly available: - -.. code:: - - # each Issuer maintains its own Status List: - https://credentials.example.com/verifiable_credentials/api/v1/status-list/2021/v1// - -See `Status List API`_ for more details. - -5. Issuer registration (Learner Credential Wallet) --------------------------------------------------- - -This step is specific for the Learner Credential Wallet storage. - -See Learner Credential Wallet `usage prerequisites`_. - -.. _issuer: https://www.w3.org/TR/vc-data-model-1.1/#dfn-issuers -.. _configuration: configuration.html#configuration -.. _management commands: configuration.html#management-commands -.. _administration site: components.html#administration-site -.. _status list API: components.html#status-list-api -.. _usage prerequisites: storages.html#usage-prerequisites \ No newline at end of file diff --git a/docs/verifiable_credentials/tech_details.rst b/docs/verifiable_credentials/tech_details.rst deleted file mode 100644 index 1dab77d6a..000000000 --- a/docs/verifiable_credentials/tech_details.rst +++ /dev/null @@ -1,57 +0,0 @@ -Implementation Details -====================== - -The following may clarify implicit internal details. - -Prerequisites -------------- - -Required initial activities. - -1. Before the main feature flag (settings) is enabled the verifiable_credentials app won't register its urlconf, admin. -2. Default built-in configuration is almost self-contained - the only required step is to configure Issuer's credentials (see `management command helper`_). If Issuer is configured in deployment environment from the start, those settings are used during the app data migration, otherwise manual Issuance Configuration edit is needed (Credentials admin site). -3. There can be a list of Issuance Configuration records, but only the last enabled is taken into account in current implementation. - -Events flow ------------ - -Here is how everything happens. - -.. image:: ../_static/images/verifiable_credentials-issuance-sequence.png - :alt: Verifiable Credentials issuance sequence diagram - -- 1 - Learner navigates to the Learner Record MFE, enters the Verifiable Credentials page. -- 2,3 - Frontend fetches all Learner's credentials (program certificates). -- 4,5 - Frontend fetches configured storages list. -- Learner chooses theirs credential (program certificate) to issue verifiable credential for. -- 6,7 - Learner initiates an issuance (standard case: single storage, experimental case: many storages). -- 8 - Issuance Line is created with given context (storage + program certificate). -- 9 - all pre-requisites are evaluated and deep-link/QR-code generated. -- Learner is present modal dialog with deep-link/QR-code to proceed with a mobile wallet app. -- 10,11 - Learner interacts with a dialog data (clicks/scans). -- 12 - Learner navigates to a mobile wallet app. -- 13 - mobile wallet app requests verifiable credential from an issuance API endpoint (on behalf of a Learner). -- verifiable_credentials application processes Issuance Line data (collects required data, composes it into a desired shape, evaluates status list data, adds signature). -- 14 - well-formed verifiable credential returned to a mobile wallet app. -- Mobile app verifies given verifiable credential (validates structure, signature, status info). - -New dependencies ----------------- - -Verifiable Credentials feature has introduced a couple of extra packages. - -didkit-python -~~~~~~~~~~~~~ - -``didkit==0.3.2`` - -A tool for verifiable credentials operations (issuance, verification, signing, validation). - -qrcode -~~~~~~ - -``qrcode==7.4.2`` - -We generate mobile deep-link QR-codes on a backend. - -.. _management command helper: configuration.html#issuer-credentials-helper diff --git a/docs/verifiable_credentials/usage.rst b/docs/verifiable_credentials/usage.rst deleted file mode 100644 index bc194262c..000000000 --- a/docs/verifiable_credentials/usage.rst +++ /dev/null @@ -1,61 +0,0 @@ -Usage -===== - -The Open edX platform allows students to earn credentials (e.g. course certificates, program certificates). Based on such credentials learners are able to create a digital cryptographically proven piece of data - a verifiable credential. - -.. note:: - Verifiable credentials are intended for machines. - -A single Open edX achievement can be used as a source for numerous verifiable credentials (identical or different data models). - -Verifiable credential includes data about: - -- who has achieved it (subject) - - student's unique decentralized identifier (DID); - - student's arbitrary personal data (optional); -- what exactly was achieved (credential) - - type (program or course certificate); - - title (program or course name, possibly courses list); -- when it happened (timestamp) - - date and time verifiable credential was created (issued); - - expiration moment (optionally); -- who proves it (issuer) - - there is always at least one issuer - organization/university/etc. who "confirms" credential's data is the Truth; -- how to check if it is still valid (status) - - there are different status check methods; - - there are different reasons for status update (source achievement revocation, for example); - -**All that data is signed, so it can't be tampered in any way - that's the point.** - -Learners --------- - -The general usage flow is the following: - -- **Student** finishes a course/program and **earns an achievement/credential** (e.g. Program Certificate X); -- **Student requests a verifiable credential** that confirms Program Certificate X exists (additional background can be included as well - e.g. average/total grade, etc.); -- The **Open edX platform creates (issues)** a verifiable credential on behalf of related Issuer (Organization/University/School); -- **Verifiable credential is uploaded** to some Learner's storage (verifiable credentials wallet, a mobile/web app); -- **Student presents** a verifiable credential to any Interested Party (another Org/University/School); -- **Interested Party verifies** a verifiable credential's status - checks if it wasn't tampered in any way; checks if it still has valid status (not expired, not revoked); - -.. note:: - Please, see the `Learner Record micro-frontend`_ for details. - -Administrators --------------- - -The Open edX users with administrator rights are able to manage/monitor the Verifiable Credentials application within the Credentials IDA admin site. - -.. note:: - Please, see the `Verifiable Credentials application`_ for details. - -Relying Parties ---------------- - -Third-parties whom a verifiable credential is presented want to ensure the current status of such artifact. That's where the `Status List`_ mechanism comes into play. - - -.. _Learner Record micro-frontend: components.html#learner-record-microfrontend -.. _Verifiable Credentials application: components.html#verifiable-credentials-application -.. _Status List: components.html#status-list-api \ No newline at end of file