Credentials

Resources

Main proposal document

UI/UX

Configure certificates on open-edx

/wiki/spaces/LEARNER/pages/13205663

Credentials Jira epic

Context

The learners can get certificates for the courses after passing all criterion. This design will allow the learners to get certificates for programs (xseries) along with the existing functionalities of certificates by creating/supporting an extensible credentials system. 

Credentials is edX's replacement for the certificates in LMS. Initially credentials service is responsible for administering programs related credentials information and awarding programs credentials to the learners. But the goal is to use credentials for all current course certificates related functionalities along with the xseries.

The credentials service is responsible for issuing credentials to learners who have met certain qualifications (e.g. completed a course, met a learning objective). Credentials can come in the form of certificates, badges, or some other form developed in the future.

For the first phase which is planned to release by the start of January 2016 we will be deploying credentials service an independently-deployable web application (IDA) as a self-contained and isolated app with django admin for programs credentials authoring, an endpoint to support credentials generation and an endpoint to get learner credentials.

Purpose

The purpose of this service is to continue awarding course certificates as we do today, and add support for issuing program (XSeries) certificates.

Milestones/Phases

  1. New Credentials Service as an IDA with Programs/XSeries Certificates generation/retrieval and authoring/administering through default django admin.

  2. Support Courses & Programs/XSeries Credentials Authoring in Studio (through new credentials service). Make a django app 'credentials_adapter' for supporting both certificates and credentials systems for course certificates.

  3. Migration of existing courses web and PDF certificates for certificates to credentials.

  4. Whitelisting / Credentials Instructor tools. Show all received certificates (for courses and XSeries) for a learner.

Requirements

  1. Continue support for awarding honor/verified/professional course certificates.

  2. Continue support for allowing recipients to share achievements via social media (LinkedIn, Facebook, Twitter).

  3. Add support for awarding programs (XSeries) certificates.

  4. Migrate existing web and PDF certificates to any new system.

    1. Preserve existing PDFs in S3.

    2. Update dashboard links to point to web certificates, instead of directly to S3.

  5. Add support for external verification of web certificates via verify.edx.org (SOL-1335, SOL-1298)

  6. New system must support multi-tenancy—partitioning credentials by site/microsite (use django sites framework).

Architecture Overview

Credentials functionality will be implemented as an isolated, self-contained, independently-deployable web application (IDA). Related support/functionality for LMS, Studio will be provided through using internal python API's which will require minimum changes. For flexibility this support/functionality could be toggled with related flags in ConfigurationModel 'CredentialsApiConfig'. The credentials rendering and preview would be part of credentials IDA.

The app 'credentials' will be responsible for getting learners credentials associations through credentials service which will be exposed via RESTful HTTP APIs (DRF: edX REST API Conventions). For communication between credentials (openedx) and credentials service (IDA) we will be using the edX REST API Client and JWT authentication (Just like the Programs).

Data Model/Classes

This design includes multiple abstract models to support course/programs specific extensible credentials configuration. This credentials configuration will be activated by the instructor through the field 'is_active'. The certificate subclasses represent certificates that can be awarded to a user. The field 'title' in abstract model 'AbstractCertificate' can be used to override the default title for a course or program (This happens particularly with longer courses where it doesn't look great on the certificate but the prof wants the full name of the course to be present on the learner dashboard and at the top of the LMS.).

Every certificate has a template representing the rendered (HTML+CSS) certificate. Most certificates will use the same template—signatures, organization logo, course name—with variations for mode 'certificate_type' (e.g. honor, verified, professional). There is a case where the certificate templates can include other assets. Hence the 'CertificateTemplateAsset model', responsible for tracking assets for these special cases. Also for now certificates uses organization app for creating a template against a particular organization or related to one of its specific modes e.g. 'honor', 'verified' etc.  This current feature allows instructor/admins to set an explicit template for the certificate at various level of depth. specific course mode override, course override, org override. then the base templates. This template override functionality will also carried over to the credentials.

The UserCredential model tracks which users have been awarded credentials. Only two statuses are supported at this time: 'awarded' and 'revoked'. To save the extra attributes e.g. 'grade' and 'whitelist' we have have a generic model 'UserCredentialAttribute'. For specificity of course related attributes we will use the prefix 'course' for the field 'namespace' e.g. 'course.grade'. The 'download_url' field will be used to distinguish between the course web certificates and course pdf certificates. This field will have the link for the PDF e.g. ff the UUID is 'abc123', the download URL should simply be 'https://<S3-HOST>/<UUID>/certificate.pdf'.



Site Configuration model

Issuing Credentials

As will be outlined below, there will be a single API endpoint to issue a credential, to avoid a proliferation of endpoints for every type of credential. The publish-subscribe pattern is used to facilitate the awarding of credentials. A single class, Accreditor, maintains a hash of credential types to subclasses of "AbstractCredentialIssuer". The accreditor is responsible for sending requests to the appropriate issuer (or issuers, should one choose to tie multiple credentials to the same credential type).


Rendering

Going forward, we only need to support HTML certificate rendering; however, that should not preclude us from supporting the rendering of PDFs or other output types in the future.

Roles/Permissions

To support course/programs specific roles for credentials service we will have to create an endpoint in edx-platform.

 

Anyone

Learner

Course Team

PM

UX

Support

System

View user credential(s)

X

X

X

X

X

X

 

Share user credential via social media

 

X

     

Create/edit/delete credential (data/template)

  

X

X

X

  

Create/edit/delete signatory

  

X

X

   

Issue credential

 

X (self-paced)

X

X

 

X

X

Revoke credential

  

X

X

 

X

 


Credentials APIs

 RESTful endpoints are below. With the exception of the user-credential GET endpoint, all endpoints will require OAuth2 or session authentication.

Some basic response codes for endpoints:

  • 200 indicates success for any operation other than a create operation
  • 201 indicates success for a create operation
  • 401 if the user is not authenticated

Pagination:

Administer credentials configurations

Credentials administration APIs for instructors and staff members.

GET/PUT/POST /api/v1/course-certificates/

Add/Update a course related certificates configuration.

{
   "course_id": "edX/DemoX/Demo_Course",
   "certificate_type": "(honor|verified|professional)",
   "template": 2,
   "title": "Demo Course Credential"(optional),
   "is_active": (True,False),
   "signatories": [2,3,4]
}

 

GET/PUT/POST /api/v1/program-certificates/

Add/Update a program related certificates configuration.

{
    "program_id": 1,
    "template": 2,
    "title": "Demo Program Credential"(optional)
	"is_active": (True,False),
    "signatories": [2,3,4]
}
POST /api/v1/user-credentials/ (in case of course)

Issue course credential for a user.

Input For Course Certificate
{
    "username": "edxapp",
    "course_id": "edx/DemoCourse/DemoX",
    "certificate_type": "(honor|verified|professional)"
    "attributes": [
		{"namespace": "course.grade", "name": "Final Grade", "value": "80"}, (optional for non whitelist course credential)
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}
 
Output
{
    "credential_type": "course-certificate",
    "credential_id": 123,
    "certificate_type": "(honor|verified|professional)",
    "username": "edxapp",
    "course_id": "edx/DemoCourse/DemoX",
    "status": "(awarded|revoked)",
    "uuid": "abc123",
    "download_url": "", (empty other than pdf certs)
	"attributes": [
		{"namespace": "course.grade", "name": "Final Grade", "value": "80"}, (optional for non whitelist course credential)
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}

 

POST /api/v1/user-credentials/ (in case of program)

Issue program credential for a user.

Input For Program Certificate
{
    "username": "edxapp",
    "program_id": 1,
	"attributes": [
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}
 
Output
{
    "credential_type": "program-certificate",
    "credential_id": 123,
    "username": "edxapp",
    "program_id": 1,
    "status": "(awarded|revoked)",
    "uuid": "abc123",
    "attributes": [
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}
GET /api/v1/users/:username/credentials/
 Get all user credentials related to a specific user.
[
    {
		"credential_type": "course-certificate",
		"credential_id": 123,
		"course_id": "edX/DemoX/Demo_Course",
		"certificate_type": "(honor|verified|professional)",
		"username": "edxapp",
		"status": "(awarded|revoked)",
		"uuid": "abc123",
		"download_url": "", (empty other than pdf certs)
		"attributes": [
			{"namespace": "course.grade", "name": "Final Grade", "value": "80"}, (optional for non whitelist course credential)
		]
    },
    {
		"credential_type": "program-certificate",
		"credential_id": 123,
		"program_id": 1,
		"username": "edxapp",
		"status": "(awarded|revoked)",
		"uuid": "abc456",
		"attributes": [
			{"namespace": "whitelist", "name": "Program Whitelist", "value": "Reason"}, (optional for whitelisting)
		]
    }
]
 
GET /api/v1/courses/:course_id/credentials/

 

Get all user credentials related to a specific course.
[
    {
		"credential_type": "course-certificate",
		"credential_id": 123,
		"course_id": "edX/DemoX/Demo_Course",
		"certificate_type": "(honor|verified|professional)",
		"username": "edxapp",
		"status": "(awarded|revoked)",
		"uuid": "abc123",
		"download_url": "", (empty for non pdf certs)
		"attributes": [
			{"namespace": "course.grade", "name": "Final Grade", "value": "80"}, (optional for non whitelist course credential)
		]
    }
	{
		"credential_type": "course-certificate",
		"credential_id": 456,
		"course_id": "edX/DemoX/Demo_Course",
		"certificate_type": "(honor|verified|professional)",
		"username": "dummy_user",
		"status": "(awarded|revoked)",
		"uuid": "abc456",
		"download_url": "", (empty for non pdf certs)
		"attributes": [
			{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
		]
    }
]

 

GET /api/v1/programs/:program_id/credentials/

Get all user credentials related to a specific program.

[
    {
		"credential_type": "program-certificate",
		"credential_id": 123,
		"program_id": 1,
		"username": "edxapp",
		"status": "(awarded|revoked)",
		"uuid": "abc456",
		"attributes": []
    },

   {
		"credential_type": "program-certificate",
		"credential_id": 456,
		"program_id": 1,
		"username": "dummy_user",
		"status": "(awarded|revoked)",
		"uuid": "abc789",
		"attributes": [
			{"namespace": "whitelist", "name": "Program Whitelist", "value": "Reason"}, (optional for whitelisting)
		]
    }
]
POST /api/v1/certificate-templates/

Add template for certificates configuration.

{
    "name": "Dummy Template Name",
    "organization_id": 1, (optional)
    "certificate_type": "(honor|verified|professional)", (optional)
    "content": "HTML content"
}

 

GET/PUT/POST /api/v1/certificate-template-assets/

Add/Update file assets for certificate templates.

{
    "name": "ABC",
    "file": "Asset file path"
}

 

GET/PUT/POST /api/v1/signatories/

Add/Update a signatory.

{
    "name": "ABC",
    "title": "XYZ",
    "image": "Path to the image"
}

 

PATCH /api/v1/user-credentials/:id

Revoke a specific user credential.

{
    "status": "revoked"
}

 

Public accessible credentials endpoints

Credentials public APIs for learners.

GET /api/v1/credentials/:uuid (in case of course)

Get credentials data for a course certificate.

{
	"credential_type": "course-certificate",
	"credential_id": 123,
	"course_id": "edX/DemoX/Demo_Course",
	"certificate_type": "(honor|verified|professional)",
	"username": "edxapp",
	"status": "(awarded|revoked)",
	"uuid": "abc123",
	"download_url": "", (empty other than pdf certs)
	"attributes": [
		{"namespace": "course.grade", "name": "Final Grade", "value": "80"}, (optional for non whitelist course credential)
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}

 

GET /api/v1/credentials/:uuid (in case of program)

Get credentials data for a program certificate.

{
	"credential_type": "program-certificate",
	"credential_id": 123,
	"program_id": 1,
	"username": "edxapp",
	"status": "(awarded|revoked)",
	"uuid": "abc456",
	"attributes": [
		{"namespace": "whitelist", "name": "Whitelist", "value": "Reason"}, (optional for whitelisting)
	]
}


Get credentials info for rendering

These APIs will be exposed by edx-platform by the credential app so that the credentials service can use this api to properly render a course/program credential/certificate.

For a complete list of meta_data required for course certificates please check the context for this HTML render view of web certificates:

 

GET  /api/v1/credentials/course_info/:username/:course_id/ (in case of course)

Get credentials metadata for a rendering of a course certificate.

{
    "full_name": "edxapp user",
    "course_name": "edX Demonstration Course",
    "organization_id": 2, (optional if a course is related to some organization)
    "meta_data": {
		"platform_name": "",
        "copy_right_text": "",
		...
     }
}

  

GET  /api/v1/credentials/program_info/:username/:program_id/ (in case of program)

Get credentials metadata for a rendering of a program certificate. 

{
    "full_name": "edxapp user",
    "program_name": "edX Demonstration Program",
    "meta_data": {
		"platform_name": "",
        "copy_right_text": "",
		...
     }
}

 

Integration

For integration we will have a simple django app "credentials" (openedx.core.djangoapps) which will serve to toggle credentials related functionality for both LMS and Studio and communicate with credentials service. This app will also be responsible for creating async credential task (celery task) for grading (checking eligibility) and sending request to credentials service in case of generating credentials for a course. In case of programs we don't need to check eligibility since programs service will use credentials endpoint with only eligible users. Also this app will expose an API (for usage by the "credentials_service") to provide necessary data related to user, course/program (their relation with the organization in case of a course).

For first phase we will have a separate IDA "credentials_service" which will have all the core functionality for credentials.

We will have another simple django app "credentials_adapter" (opened.core.djangoapps) which will have same view as certificates (this is to support both certificates and credentials during migration). The purpose of this app would be to chose between certificates or credentials system for underlying functionalities for course certificates since we will have web certificates courses in current certificates system too also we will have to support PDF certificates (deprecated).

 

Credentials program admin flow


 



Credentials course admin flow




Credentials learner flow

For a leaner the certificates urls which are displayed on the dashboard will be according to certificates or credentials system.


Migration

For first phase this is not necessary because the new system will only handle the programs (xseries) credentials. Our current models can support almost all existing use cases.

In next step we have to migrate the existing course certificates data to the new credentials system too. So until we have migrated all data from existing course certificates models to new credential service we will have a credentials adapter wrapper "credentials_adapter" in place which will check if that course has certs configuration in old certificates system or in new credentials system. So if a course related certs configuration is in old system then credentials adapter service will keep serving the certificates from old system and once a course related certs a migrated to new credentials system then credentials adapter can start serving that course certs from new credentials system. This credentials adapter will increase some overhead but this way we can avoid any downtime until we have migrated all course certificates data to new credentials system.

By using the credentials adapter we will migrate certificates data per course at a time and once migration for that course is complete we will add entry for it in the model "CredentialsMigrationModel" and credentials adapter can start using the new credentials system for that course. If a course has no configuration then our credentials adapter will always point to new credentials system for serving credentials.

Migration Adapter model for course certificate migration:

Edge case: In this approach we have to figure out how to prevent certificates generation for that course for which migration is in progress.

 Ans: We will be using credentials adapter to prevent cert generation for a course whose migration is in progress and the status will be saved in the model "CredentialsMigrationModel".

Things to consider: Currently the course title override value and signatories are saved with the course in mongo modulestore. Schema is also changed for new credentials system.

Ans: We will be using django management command which will first add entry in credentials migration model "CredentialsMigrationModel" with the status "pending" status then it will fetch the certificates configuration for a course by using modulestore and after manipulation/formatting the certificates data according to new credentials schema, will send a create config http request to the new credentials system. Then after the configuration is created the management command will send bulk create request for user credentials (maybe in chunks like 1000 learners for a course at time) by using edx-rest-api-client. Once the migration is complete for the course, the management command will mark the entry in credential migration table as "completed". This way the credentials adapter will start using new credentials system for that course too.

Product question: Currently the signatory, course override title and basic configuration are saved inside the course (mongo modulestore) so that’s way they are also part of the course import export. Do we need this functionality for new credentials system? If that’s the case then do we have the re-run scenario for programs?

Ans: This is being discussed on the credentials google docs.

Course certificates analytics

Some basic analytics related to course certificates for migration point of view.

https://docs.google.com/spreadsheets/d/1CzCqK0-zASLK63M7ZN_k-4ARyC77JXiFFH5X2OCH5rw/edit#gid=0&vpid=A1

 

Web Certificates:

 

Total courses

Total cert issued

Min cert count

Max cert count

Avg cert count

171

60599

1

4839

354

 

Pdf Certificates:

 

Total courses

Total cert issued

Min cert count

Max cert count

Avg cert count

687

594716

1

14482

865

 

Courses with whitelists:

 

Total courses

Min whitelist users

Max whitelist users

Avg whitelist users

69

1

1623

70

 

Extra information related to Certificates:

 

Total Templates

Total template assets

5

30