Open Badges Version 2.1
Spec Version 2.1
Document Version: | 4 |
Date Issued: | November 27, 2023 |
Status: | This document is made available for adoption by the public community at large. |
This version: | https://www.imsglobal.org/spec/ob/v2p1/ |
Latest version: | https://www.imsglobal.org/spec/ob/latest/ |
Errata: | https://www.imsglobal.org/spec/ob/v2p1/errata/ |
IPR and Distribution Notice
Recipients of this document are requested to submit, with their comments, notification of any relevant patent claims or other intellectual property rights of which they may be aware that might be infringed by any implementation of the specification set forth in this document, and to provide supporting documentation.
1EdTech takes no position regarding the validity or scope of any intellectual property or other rights that might be claimed to pertain implementation or use of the technology described in this document or the extent to which any license under such rights might or might not be available; neither does it represent that it has made any effort to identify any such rights. Information on 1EdTech's procedures with respect to rights in 1EdTech specifications can be found at the 1EdTech Intellectual Property Rights webpage: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf .
The following participating organizations have made explicit license commitments to this specification:
Org name | Date election made | Necessary claims | Type |
---|---|---|---|
Concentric Sky | October 24, 2019 | No | RF RAND (Required & Optional Elements) |
Digital Knowledge | October 11, 2019 | No | RF RAND (Required & Optional Elements) |
Washington State Board for Community and Technical Colleges (WSBCTC) | October 4, 2019 | No | RF RAND (Required & Optional Elements) |
Credly | October 3, 2019 | No | RF RAND (Required & Optional Elements) |
Use of this specification to develop products or services is governed by the license with 1EdTech found on the 1EdTech website: http://www.imsglobal.org/speclicense.html.
Permission is granted to all parties to use excerpts from this document as needed in producing requests for proposals.
The limited permissions granted above are perpetual and will not be revoked by 1EdTech or its successors or assigns.
THIS SPECIFICATION IS BEING OFFERED WITHOUT ANY WARRANTY WHATSOEVER, AND IN PARTICULAR, ANY WARRANTY OF NONINFRINGEMENT IS EXPRESSLY DISCLAIMED. ANY USE OF THIS SPECIFICATION SHALL BE MADE ENTIRELY AT THE IMPLEMENTER'S OWN RISK, AND NEITHER THE CONSORTIUM, NOR ANY OF ITS MEMBERS OR SUBMITTERS, SHALL HAVE ANY LIABILITY WHATSOEVER TO ANY IMPLEMENTER OR THIRD PARTY FOR ANY DAMAGES OF ANY NATURE WHATSOEVER, DIRECTLY OR INDIRECTLY, ARISING FROM THE USE OF THIS SPECIFICATION.
Public contributions, comments and questions can be posted here: http://www.imsglobal.org/forums/ims-glc-public-forums-and-resources .
© 2023 1EdTech™ Consortium, Inc. All Rights Reserved.
Trademark information: http://www.imsglobal.org/copyright.html
Abstract
Open Badges are visual symbols of accomplishments packed with verifiable metadata according to the Open Badges specification. The Open Badges 2.0 specification [OB-20] defines the properties necessary to define an achievement and award it to a recipient, as well as procedures for verifying badge authenticity and “baking” badge information into portable image files. It includes term definitions for representations of data in Open Badges. The Open Badges 2.1 specification [OB-21] defines an API for exchanging badge information. These term definitions appear in the current context at https://purl.imsglobal.org/spec/ob/v2p1/context/ob_v2p1.jsonld.
1. Introduction
1.1 Design Goals and Rationale
This section is non-normative.
Open Badges 2.1 is a specification that adds the Badge Connect® API to Open Badges that allows badge recipients to easily move their Assertions between platforms to streamline the experience of earning and using Open Badges. The initial scope for this specification will cover Assertions and Profiles, with potential additions in future versions of other types of data held by applications in the various Open Badges ecosystem roles of Issuer, Displayer, and Host.
1.2 Use cases
This section is non-normative.
The following use cases are supported by this specification:
A recipient of an Assertion wants to import historically-issued badges into a chosen Host from an Issuer platform. |
A user wishes to authorize an Issuer to push awarded Assertions to their chosen Host upon issue. |
A user wishes to connect their Assertions to a recruiting platform. |
A user wishes to move their badges from one Host to another Host. |
A Consumer wishes to obtain plaintext recipient identifier, to clearly understand the recipient profile in their badges. |
An Issuer platform wishes to register a new recipient identifier on a recipient profile to which it would award badges. |
1.3 Conformance and Certification
As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.
The key words MAY, MUST, MUST NOT, OPTIONAL, RECOMMENDED, REQUIRED, SHALL, SHALL NOT, SHOULD, and SHOULD NOT in this document are to be interpreted as described in [RFC2119].
An implementation of this specification that fails to implement a MUST/REQUIRED/SHALL requirement or fails to abide by a MUST NOT/SHALL NOT prohibition is considered nonconformant. SHOULD/SHOULD NOT/RECOMMENDED statements constitute a best practice. Ignoring a best practice does not violate conformance but a decision to disregard such guidance should be carefully considered. MAY/OPTIONAL statements indicate that implementers are entirely free to choose whether or not to implement the option.
The Conformance and Certification Guide for this specification may introduce greater normative constraints than those defined here for specific service or implementation categories.
1.4 Specification Documents
The full set of documents is comprised of the following documents:
OpenAPI 3.0 Files for the Badge Connect® API
From the OpenAPI Specification [OPENAPIS],
The Open API Specification (OAS) defines a standard, programming language-agnostic interface description for HTTP APIs, which allows both humans and computers to discover and understand the capabilities of a service without requiring access to source code, additional documentation, or inspection of network traffic. When properly defined via OpenAPI, a consumer can understand and interact with the remote service with a minimal amount of implementation logic. Similar to what interface descriptions have done for lower-level programming, the OpenAPI Specification removes guesswork in calling a service.
This standard has OpenAPI 3.0 files for the Badge Connect® API in both JSON and YAML format:
JSON Schema Files for Open Badges Badge Connect(TM) API v2.1
Badge Connect® API JSON-LD Context File
From the JSON-LD 1.1 Specification [json-ld11],
When two people communicate with one another, the conversation takes place in a shared environment, typically called "the context of the conversation". This shared context allows the individuals to use shortcut terms, like the first name of a mutual friend, to communicate more quickly but without losing accuracy. A context in JSON-LD works in the same way. It allows two applications to use shortcut terms to communicate with one another more efficiently, but without losing accuracy.
Simply speaking, a context is used to map terms to IRIs. Terms are case sensitive and any valid string that is not a reserved JSON-LD keyword can be used as a term.
This specification includes this JSON-LD Context file:
1.5 Terminology
The following terms are used throughout this document.
- Assertion: A representation of an awarded badge, used to share information about a badge belonging to one recipient.
- Backpack: A term originally used to describe Open Badges services that provide importing, aggregation, and hosting features for recipients. These services match most closely with the role we now define as an Open Badge “Host” application. May also refer to the Mozilla Backpack.
- BadgeClass: A collection of information about the accomplishment recognized by the Open Badge. Many assertions may be created corresponding to one BadgeClass.
- Badge Connect® API: Name of the RESTful web service for transfering assertions and profiles between systems.
- Badge Issuer: A service that allows for the creation of BadgeClasses and the subsequent issuing of Assertions to recipients that conform to the Open Badges specification. Beginning with Open Badges 2.0, the candidate platform must issue a valid baked badge and demonstrate how the badge is retrieved by the recipient.
- Badge Displayer: An application that displays verified badges to viewers. Beginning with Open Badges 2.0, the candidate platform must display a minimum set of badge metadata and support viewer-initiated verification of a badge.
- Badge Host: An application that can import, aggregate, and publicly host Assertions for recipients. It also supports export of badges at user request. Beginning with Open Badges 2.0, the candidate platform must be able to import all formats of Open Badges as well as prove that badge metadata is not lost upon export of the badge.
- Baked badge: Badge Assertions may be “baked” into image files as portable credentials.
- Candidate platform: A platform implementing the Open Badges specification with the intent to obtain certification from IMS. They may be in the process to obtain certification.
- Criteria: Detailed information about what must be done in order to be recognized with an assertion of a particular BadgeClass. Potential recipients may use criteria to understand what they must do; consumers may use criteria to understand what recipients did in order to earn the badge.
- Evidence: Links to and descriptions of evidence related to the issuance of an Assertion, such as portfolio items or narratives that describe a badge recipient's work.
- Extensions: Extensions are a means for issuers to add additional functionality through the use of metadata on Badge Objects beyond what the standard specifies itself.
- Validation and verification (of badge assertions): Data validation is a procedure that ensures a cluster of data objects that form an Open Badge are appropriately formatted, published, and linked and that each data object conforms to requirements for its class. Validation of all data class instances used in an Open Badge is a part of badge verification. Verification is the process of ensuring the data that makes up an Open Badge is correct. It includes a number of data validation checks as well as procedures to ensure the badge is trustworthy. Verification is distinct from compliance certification for applications and services that implement the specification, though verification is typically a component of certification programs. See Verification in the current specification.
2. API
Badge Connect® defines a JSON API protocol to be implemented by applications serving in the roles of Provider and Consumer. Typically Relying Parties SHOULD be certified Open Badges services in the Open Badges roles of Displayer or Issuer, though Providers may also be relying parties to serve the Host to Host transfer use case. Badge Connect® API uses OAuth 2.0 for authentication, granular resource-based permission scopes, and offers a number of required endpoints that MUST be implemented by Providers and Consumers or both.
2.1 Architecture
There are five key components to the Badge Connect® API architecture.
- Resource Owner
- This is the user that owns the resources (badges) that are on the Provider.
- Web Browser
- This is the web browser application that the user interacts with.
- Consumer
- This is the web application that interacts with the Provider on behalf of the resource owner. This component is called the Consumer in the IMS Security Framework [SEC-10].
- Authorization Server
- This is a server that implements the OAuth 2.0 endpoints on behalf of the Provider. In many systems, the Authorization Server and the Provider are combined.
- Provider
- This is the resource server that has the protected resources (badges). This component is called the Provider in the IMS Security Framework [SEC-10].
The role of each component during Registration, Obtaining Tokens, and Authenticating with Tokens are described below.
2.2 Authentication
A Consumer requests a token scoped for access to Open Badges Assertions on a Provider that belong to a user (resource owner) of that Provider service, using an OAuth 2.0 Authorization Code Grant as described in Section 4.2 of the IMS Security Framework [SEC-10]. Once a Consumer obtains a code, it exchanges the code for an access token and optionally a refresh token. Subsequent API requests are authenticated with the access token until its expiration. If the Provider previously provided a refresh token, the access token can be renewed.
2.2.1 Registration
The user starts on the Consumer application and is offered the chance to connect that application to their chosen Provider. The user supplies the Consumer with the Provider domain authority or selects their Provider from a list.
When presented with a new target Provider by which the Consumer is attempting to gain an access token from, it MUST register itself with the Provider and receive client credentials in order to proceed with the OAuth 2.0 token exchange. The Consumer and Provider MUST implement [RFC7591].
If the Consumer does not know the Provider's registration URL, it MUST request the Manifest as shown this sequence diagram:
The registration request MUST use HTTPS (TLS 1.2 or 1.3). An example registration request may look like:
POST /o/register HTTP/1.1 Content-Type: application/json Accept: application/json Host: badge-host.example.com { "client_name": "Badge Issuer", "client_uri": "https://issuer.example.com", "logo_uri": "https://issuer.example.com/logo.png", "tos_uri": "https://issuer.example.com/terms-of-service", "policy_uri": "https://issuer.example.com/privacy-policy", "software_id": "13dcdc83-fc0d-4c8d-9159-6461da297388", "software_version": "54dfc83-fc0d-4c8d-9159-6461da297388", "redirect_uris": [ "https://issuer.example.com/o/redirect" ], "token_endpoint_auth_method": "client_secret_basic", "grant_types": [ "authorization_code", "refresh_token" ], "response_types": [ "code" ], "scope": "YOUR_REQUESTED_SPACE_SEPARATED_LIST_OF_SCOPES" }
The properties of the JSON body MUST be implemented as described in the following table. All URLs MUST use HTTPS (e.g. https://example.com/logo.png) and all URLs MUST have the same hostname. All required properties MUST be present in the registration request in order for it to be accepted by the Provider.
Name | Type | Required | Description |
---|---|---|---|
client_name | String | Yes | The human-readable name of the Consumer. |
client_uri | URI | Yes | A page that which describes the Consumer. |
logo_uri | URI | Yes | The logo of the Consumer. The logo image uri should resolve to an image file with a square aspect ratio in either PNG or SVG format. Recommended resolution: 512x512px. |
tos_uri | URI | Yes | The Terms of Service of the Consumer. |
policy_uri | URI | Yes | The Privacy Policy of the Consumer. |
software_id | String | Yes | A unique idenfitier assigned by the client developer. As described in [RFC7591], it SHOULD remain the same for all instances of the client software. |
software_version | String | Yes | A version identifier string for the client software. The value SHOULD change on any update to the client software. |
redirect_uris | URI | Yes (Array) | Array of redirection URI strings for use in the OAuth 2.0 flow. |
token_endpoint_auth_method | String | No |
String indicator of the requested authentication method for the token endpoint. In this specification
only "client_secret_basic"
is allowed:
|
grant_types | String | No (Array) |
Array of OAuth 2.0 grant type strings. In this specification only "authorization_code" and
refresh_token" are allowed:
|
response_types | String | No (Array) |
Array of OAuth 2.0 response type strings. In this specification only "code" is allowed:
|
scope | String | No | String containing a space-separated list of scope values that this client is permitted to use when requesting access tokens. Scopes are defined in Scopes. If omitted, the Provider MAY register a client with a default set of scopes. |
If the Provider accepts the registration request, it will store the information provided in the request and generate a set of client credentials for the Consumer to use when requesting access tokens.
All the information provided by the Consumer MUST be returned to the Consumer, including modifications to the properties as the Provider deems necessary. This MAY include changes to scopes that the Provider chooses to support. Consumers are encouraged to fail gracefully if a requested scope was not returned by the Provider by either supporting a subset of the intended functionality or by providing messaging to the Resource Owner.
The Provider MAY reject a registration request if the value of one of the Consumer's metadata fields is invalid. The Provider MAY choose to substitute a valid value for any requested parameter of a Consumer's metadata. Implementers should take note that substitution MAY include changes to the permitted scopes.
For the purposes of registering a Consumer, a Provider MAY limit the scopes it supports to those revelant to Badge Connect®.
HTTP/1.1 201 Created Content-Type: application/json Cache-Control: no-store Pragma: no-cache { "client_id": "BADGECONNECT_s6BhdRkqt3", "client_secret": "czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3", "client_id_issued_at": 1558280111, "client_secret_expires_at": 1558290111, "client_name": "Badge Issuer", "client_uri": "https://issuer.example.com", "logo_uri": "https://issuer.example.com/logo.png", "tos_uri": "https://issuer.example.com/terms-of-service", "policy_uri": "https://issuer.example.com/privacy-policy", "software_id": "13dcdc83-fc0d-4c8d-9159-6461da297388", "software_version": "54dfc83-fc0d-4c8d-9159-6461da297388", "redirect_uris": [ "https://issuer.example.com/o/redirect" ], "token_endpoint_auth_method": "client_secret_basic", "grant_types": [ "authorization_code", "refresh_token" ], "response_types": [ "code" ], "scope": "YOUR_REQUESTED_SPACE_SEPARATED_LIST_OF_SCOPES" }
The following table describes the properties present in the client registration response that were not included in the request. These are all REQUIRED properties.
Name | Type | Required | Description |
---|---|---|---|
client_id | String | Yes | An OAuth 2.0 client identifier string. The value SHOULD NOT be currently valid for any other registered client. |
client_secret | String | Yes | An OAuth 2.0 client secret string. |
client_id_issued_at | Integer | Yes | The time at which the client_id was issued. The time is represented as the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time of issuance. |
client_secret_expires_at | Integer | Yes | The time at which the client_secret will expire. MAY be 0 for no expiration. The time is represented as the number of seconds from 1970-01-01T00:00:00Z as measured in UTC until the date/time of expiration. |
Implementers are encouraged to use existing libraries as [RFC7591] supports internationalization among other nuances that may not be realized in an in-house solution.
2.2.2 Obtaining Tokens
After the Consumer is registered with the Provider as described in Registration, the Consumer then MAY initiate an authorization request as described in Section 4.2 of the IMS Security Framework [SEC-10] by redirecting the user to the Provider's authorizationUrl as declared in the Provider's Badge Connect® Manifest.
All required properties must be included in the authorization request.
Name | Type | Required | Description |
---|---|---|---|
response_type | String | Yes | Value MUST be set to "code". |
client_id | String | Yes |
The client identifier. MUST be client_id provided in the
Registration response.
|
redirect_uri | URI | Yes |
The Consumer's redirection endpoint. MUST match one of the redirect_uris
in the Registration request. Although this is optional in
the IMS Security Framework [SEC-10], it is REQUIRED by this specification.
|
scope | String | Yes | The scope of the authorization request. This is a space delimited list of scopes. |
state | String | Yes | An opaque value used by the client to maintain state between the request and callback. |
code_challenge | String | Yes | This is BASE64URL-ENCODE(SHA256(ASCII(code_verifier))). |
code_challenge_method | String | Yes | This MUST have a value of S256 i.e. the SHA256 code verifier transformation method is used. |
An example authorization request (line breaks for display purposes only):
GET /authorize?
response_type=code
&client_id=BADGECONNECT_s6BhdRkqt3
&state=xyzjklabc
&scope=SPACE_SEPARATED_STRING_OF_REQUESTED_SCOPES
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challange_method=S256
&redirect_uri=https%3A%2F%2Fbadgehost.example.com%2Fo%2Fredirect HTTP/1.1
Host: www.example.com
If the Provider does not recognize the Consumer's redirection endpoint from a prior
connection with this Consumer, the Provider SHOULD throw an error specifying that
the redirection endpoint is not applicable to any registered client and registration
should be made before proceeding. If the redirect_uri
matches the known
client_id
,
the Provider MAY honor the request to present the
user or resource owner with the option to authorize the request. If the Provider recognizes
the Consumer, the Provider MAY skip the need to register the client again.
If the user authorizes the Consumer to access their resources with the
requested scopes, the Provider MUST redirect the user back to the redirect_uri
with a code
query string parameter.
With the supplied code, the Consumer SHOULD attempt to exchange the code for a
token. The Consumer makes an authorization grant POST request to the Provider's
tokenUrl, as declared in the Provider's Badge Connect® Manifest.
The HTTP POST request MUST include a Basic authorization header with the client_id
and client_secret
provided by the response to the registrationUrl endpoint.
The body of the request MUST include the following form fields:
Name | Type | Required | Description |
---|---|---|---|
grant_type | String | Yes | Value MUST be set to "authorization_code". |
code | String | Yes | The authorization code received from the authorization server. |
redirect_uri | URI | Yes | The Consumer's redirection endpoint. |
scope | String | Yes | The scope of the access request. |
code_verifier | String | Yes | The PKCE code verifier. |
An example token request:
POST /badge/connect/auth/token HTTP/1.1 Host: www.example.com Authorization: Basic QkFER0VDT05ORUNUX3M2QmhkUmtxdDM6Y3paQ2FHUlNhM0YwTXpvM1JtcG1jREJhUW5JeFMzUkVVbUp1Wmxaa2JVbDM= Content-Type: application/x-www-form-urlencoded grant_type=authorization_code &code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4 &redirect_uri=https://badgehost.example.com/o/redirect &scope=SPACE_SEPARATED_STRING_OF_REQUESTED_SCOPES &code_verifier=YOUR_GENERATED_CODE_VERIFIER
If the authorization server finds the request to be a valid, it generates and returns an access token and optionally a refresh token.
If the request fails, the Provider SHOULD return a response as described in RFC6749.
2.2.3 Authenticating with Tokens
After obtaining a token using the method above, a Consumer MAY request resources
controlled by the resource owner from Provider endpoints using the token in the HTTP
Authorization header. An example follows, where 2YotnFZFEjr1zCsicMWpAA
is
the token:
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
2.2.4 Revocation by Resource Owner
Provider platforms MUST provide a list of authorized clients to the resource owner for review. The list SHOULD identify the Consumer and when the grant was created. From this list the resource owner MUST be able to revoke the Consumer's access.
Subsequent attempts to use the relevant revoked access or refresh tokens SHOULD result in a 401 UNAUTHENTICATED error.
2.2.5 Revocation by Consumer
Provider platforms MAY provide a mechanism to revoke both types of tokens by providing a token revocation endpoint in their manifest file [RFC7009]. This revocation endpoint allows a Consumer to invalidate its tokens if the end-user logs out, changes identity, or removes the respective Provider.
If token revocation endpoints are implemented they MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens.
Revocation by Consumer is not part of the IMS Security Framework [SEC-10]. If the implementer decides to implement it, they SHOULD follow [RFC7009].
Revocation Request
The Consumer makes a POST request to the Provider's token revocation URL, as declared in the Provider's Badge
Connect® Manifest.
The HTTP request entity-body MUST contain a token
parameter containing the refresh token or
access token.
Relying Parties MAY also pass a token_type_hint
parameter with a value of
access_token
or refresh_token
.
An example revocation request:
POST /badge/connect/auth/revoke_token HTTP/1.1 Host: www.example.com Content-Type: application/x-www-form-urlencoded token=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4 &token_type_hint=access_token
2.3 Scopes
Access to resources in the Badge Connect® API require an access token. These access tokens have a permissioned scope when they are created and inform the responding application which resources the entity has access to.
Name | Description |
---|---|
https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.readonly | Permission to read assertions for the authenticated entity. |
https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.create | Permission to create assertions for the authenticated entity. |
https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.readonly | Permission to read the profile for the authenticated entity. |
https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.update | Permission to update the profile for the authenticated entity. |
offline_access | Permission to issue a refresh_token along with the access_token . |
2.4 Manifest
All Providers MUST implement a JSON manifest file which contains configuration information about their implementation, such as scope support, redirect URIs, and branding information.
Providers MUST serve the manifest at the well-known path
/.well-known/badgeconnect.json
on the relevant service
domain compliant with [RFC5785]. The manifest MUST be provided over secure TLS 1.2 or 1.3 protocol
e.g. https://YOUR_DOMAIN/.well-known/badgeconnect.json
.
Requesting Manifests
Upon requesting a Manifest file from a Provider,
the requester SHOULD respect the Cache-Control
and
Expires
headers if present in the response and configure
local cache to match the directives it declares. If directives include
one of no-cache, no-store
, the requester SHOULD NOT cache
the data for future interactions. If directives include
max-age
or if an Expires
header is present,
the requester SHOULD cache the manifest file data, if valid, up to the
expiration indicated, either at the time indicated by the Expires
header or max-age seconds from request time.
An Etag
header MAY be offered with the Manifest file
response. If so, after a resource's declared expiration, a requester
MAY include an If-None-Match
header containing the value
of the Etag to check if the resource is still fresh. If so the server
may return a 304 Not Modified
response status code, and a
new Expires
or Cache-Control
header MAY be
included, which the requester SHOULD use to update the cache expiration.
Manifest Structure
{
"@context": "https://purl.imsglobal.org/spec/ob/v2p1/ob_v2p1.jsonld",
"id": "https://badgehost.example.com/.well-known/badgeconnect.json",
"badgeConnectAPI": [{
"name": "A Badge Host",
"image": "https://badgehost.example.com/logo.png",
"apiBase": "https://badgehost.example.com/api/ims/ob/v2p1",
"version": "v2p1",
"termsOfServiceUrl": "https://badgehost.example.com/terms",
"privacyPolicyUrl": "https://badgehost.example.com/privacy",
"scopesOffered": [
"https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.readonly",
"https://purl.imsglobal.org/spec/ob/v2p1/scope/assertion.create",
"https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.readonly",
"https://purl.imsglobal.org/spec/ob/v2p1/scope/profile.update"
],
"registrationUrl": "https://badgehost.example.com/o/register",
"authorizationUrl": "https://badgehost.example.com/o/auth",
"tokenUrl": "https://badgehost.example.com/o/token",
"tokenRevocationUrl": "https://badgehost.example.com/o/revoke_token"
}]
}
Manifest Properties
For the URL properties below, it is not required that the top-level domains match. However, implementors SHOULD use the manifest location's top-level domain whenever possible.
Property | Type | Required | Description |
---|---|---|---|
name |
String | Yes | The name of the platform supporting the API. This SHOULD reflect the user-facing identity of the platform requesting authorization. |
image |
URI | No | An image representing the platform. May be a URI to a hosted image or a Data URI. The logo image uri should resolve to an image file with a square aspect ratio in either PNG or SVG format. Recommended resolution: 512x512px. |
apiBase |
URI | Yes | Fully qualified URL that will be concatenated with the API endpoints. It must end with the path
fragment "/ims/ob/v2p1". It SHOULD NOT have a trailing slash "/".
E.g. apiBase + "/assertions"
|
version |
String | Yes | A string representing the implemented version. MUST be in the format of vMAJORpMINOR where
MAJOR and MINOR are integers. v2p1 is the correct string
for this specification version. |
termsOfServiceUrl |
URI | Yes | Fully qualified URL to the platform's terms of service. Other platforms SHOULD link to this resource as part of their authorization interface. |
privacyPolicyUrl |
URI | Yes | Fully qualified URL to the platform's privacy policy. Other platforms SHOULD link to this resource as part of their authorization interface. |
scopesOffered |
String | Yes (Array) | An array of strings listing the scopes supported by the Provider in the form of fully qualified URLs to the scope descriptors. |
registrationUrl |
URI | Yes | A fully qualified URL to which the Consumer would make the client registration request to before performing the authorization flow. |
authorizationUrl |
URI | Yes | A fully qualified URL to the Provider's authorization endpoint. |
tokenUrl |
URI | Yes | A fully qualified URL to the Provider's token request endpoint for exchanging an authorization code for a bearer token. |
tokenRevocationUrl |
URI | No | A fully qualified URL to the Provider's token revocation endpoint for invalidating an existing refresh token
or access token. When this property is omitted or has a null value, it will be assumed that
the Provider does not support token revocation by a Consumer. |
2.5 Response Envelope
Responses from all Badge Connect®-specific APIs in this document are wrapped in a JSON envelope. All
response envelopes have a
status
property and one or more result properties. The result property name(s) and data types
are defined in the Responses section for each endpoint.
Responses related to standarized OAuth requests should use the prescribed format in their respective RFC.
2.5.1 Status
The "status" property MUST appear on all responses.
Name | Type | Required | Description |
---|---|---|---|
error | String | Yes | A nullable string and the human-readable message describing the problem. |
statusCode | Integer | Yes | The HTTP status code of the response. |
statusText | String | Yes | A string matching one of the enumerated and allowed values for the given endpoint. |
2.5.2 Pagination
Pagination of results is controlled by two query string parameters appended to the request.
limit
- the number of results to returnoffset
- the index of the first record to return (zero indexed)
The HTTP Link
header MUST appear when a list response is incomplete and MAY appear for complete
responses.
It is RECOMMENDED that Provider implementations honor the limit
when forming the response,
but MAY use any limit, or no limit.
It is RECOMMENDED that Provider implementations pass the total result count back to the requester. When the total
result count is not known, this MUST be omitted. The value MUST be provided in the custom HTTP header:
X-Total-Count
.
The header MUST support all of the following link relations (rel
values):
Name | Required | Description |
---|---|---|
next | Yes | The link relation for the immediate next page of results. This MUST appear when the current list response is incomplete. |
last | Yes | The link relation for the last page of results. This MUST always appear. |
first | Yes | The link relation for the first page of results. This MUST always appear. |
prev | Yes | The link relation for the immediate previous page of results. This MUST appear when the offset is greater than zero. |
An example of Link header pagination, line breaks added for readability:
Link:
<https://host.example.com/v1/assertions?limit=10&offset=20>; rel="next",
<https://host.example.com/v1/assertions?limit=3&offset=500>; rel="last",
<https://host.example.com/v1/assertions?limit=10&offset=0>; rel="first",
<https://host.example.com/v1/assertions?limit=10&offset=0>; rel="prev"
2.6 Assertion Payload
An Assertion Payload contains either a signed or unsigned Assertion [OB-20]. If both are specified, the unsigned Assertion MUST be ignored. Null values MAY be omitted.
Three examples:
{
"assertion": { ... },
"signedAssertion": null
}
{
"assertion": null,
"signedAssertion": "abced..."
}
{
"assertion": { ... }
}
Property | Expected Type | Required | Description |
---|---|---|---|
assertion |
Assertion | No | An unsigned Assertion [OB-20] object in serialized JSON-LD. |
signedAssertion |
String | No | A signed Assertion in JWS Compact JWS Serialization format. |
2.7 Endpoints
2.7.1 Assertions
GET /assertions | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description | Fetch Assertions for the supplied parameters and authentication token. The response envelope contains a list of zero or more matching signed Assertions and a list of zero or more matching unsigned assertions. There SHOULD be only one assertion (signed or unsigned) for any particular assertion ID as the IDs are intended to be globally unique. The Provider SHOULD return Assertions (signed and unsigned) ordered by last update, descending and SHOULD return only Assertions (signed and unsigned) updated after the timestamp requested if supplied. | |||||||||||||||||||||
Query Parameters |
|
|||||||||||||||||||||
Responses |
|
POST /assertions | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description | Create or update an Assertion. The posted data MUST be an Assertion Payload. Upon receiving any Assertion, the Provider SHOULD verify the Assertion, whether it is the first time seen or a subsequent update. The data posted by the Consumer SHOULD not be implicitly trusted to be an accurate representation of the Assertion. | |||||||||||||||||||||
Responses |
|
2.7.2 Profile
GET /profile | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description | Fetch the profile for the supplied authentication token. For a successful result, the Provider MUST return
a valid OB Profile instance.
Profiles that are received MAY contain attributes that a Host SHOULD authenticate before using in practice. |
|||||||||||||||||||||
Responses |
|
POST /profile | ||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Description | Update the profile for the authenticate entity. The request SHOULD only include profile identifier properties to be added to the profile, not any existing data. Successful request responses will be the same as GET Profile and may not include the patched values (as the Provider may be waiting for asynchronous processes to complete before accepting the value). The value may never become part of the published profile. A Provider MAY respond with 400 BAD_REQUEST to reject data that is known immediately to not be acceptable by the platform, e.g. to reject a "telephone" property if the Provider cannot validate telephone numbers. | |||||||||||||||||||||
Responses |
|
2.8 Retry Behavior
Receivers of requests MAY implement a Retry-After header to indicate a period of time to wait before attempting the request again.
If no Retry-After header is present and the response is non-2XX, it is recommended to retry the request in 30 minutes for an additional two attempts. After which, it MAY be desirable to alert the recipient that there is an issue with the connection (e.g. perhaps they need to reauthenticate or manually trigger the request when they believe services are back up).
2.9 Responses
2.9.1 200 GET Assertions Response
Property | Type | Required | Description |
---|---|---|---|
status |
Status | Yes | The Status object describing the success or failure of the request. |
assertions |
Assertion | No (Array) | The matching unsigned Assertions. The total number of unsigned and signed assertions should not exceed the pagination limit. Not required if there are no unsigned assertions. |
signedAssertions |
String | No (Array) | The matching signed Assertions in JWS Compact Serializion format. The total number of unsigned and signed assertions should not exceed the pagination limit. Not required if there are no signed assertions. |
{
"status": {
"error": null,
"statusCode": 200,
"statusText": "OK"
},
"assertions": [
{
"@context": "https://w3id.org/openbadges/v2",
"id": "https://issuer.example.com/api/v20/assertion/1234567",
"type": "Assertion",
...
}
],
"signedAssertions": [
"eyJhbGciOiJSUzI1NiJ9.ew0KICAiQGNvbnRleHQiOiAiaHR0cHM6Ly93M2lkLm9yZy9vcGVuYmFkZ2VzL3YyIiwNCiAgInR5cGUiOiAiQXNzZXJ0aW9uIiwNCiAgImlkIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3RpY3MtYmFkZ2UuanNvbiIsDQogICJyZWNpcGllbnQiOiB7DQogICAgInR5cGUiOiAiZW1haWwiLA0KICAgICJoYXNoZWQiOiB0cnVlLA0KICAgICJzYWx0IjogImRlYWRzZWEiLA0KICAgICJpZGVudGl0eSI6ICJzaGEyNTYkYzdlZjg2NDA1YmE3MWI4NWFjZDhlMmU5NTE2NmM0YjExMTQ0ODA4OWYyZTE1OTlmNDJmZTFiYmE0NmU4NjVjNSINCiAgfSwNCiAgImltYWdlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3QtYmFkZ2UucG5nIiwNCiAgImV2aWRlbmNlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvYmV0aHMtcm9ib3Qtd29yay5odG1sIiwNCiAgImlzc3VlZE9uIjogIjIwMTYtMTItMzFUMjM6NTk6NTlaIiwNCiAgImJhZGdlIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvcm9ib3RpY3MtYmFkZ2UuanNvbiIsDQogICJ2ZXJpZnkiOiB7DQogICAgInR5cGUiOiAiU2lnbmVkQmFkZ2UiLA0KICAgICJjcmVhdG9yIjogImh0dHBzOi8vZXhhbXBsZS5vcmcvcHVibGljS2V5Ig0KICB9DQp9.Liv4CLviFH20_6RciUWf-jrUvMAecxT4KZ_gLHAeT_chrsCvBEE1uwgtwiarIs9acFfMi0FJzrGye6mhdHf3Kjv_6P7BsG3RPkYgK6-5i9uZv4QAIlvfNclWAoWUt4j0_Kip2ftzzWwc5old01nJRtudZHxo5eGosSPlztGRE9G_g_cTj32tz3fG92E2azPmbt7026G91rq80Mi-9c4bZm2EgrcwNBjO0p1mbKYXLIAAkOMuJZ_8S4Go8S0Sg3xC6ZCn03zWuXCP6bdY_jJx2BpmvqC3H55xWIU8p5c9RxI8YifPMmJq8ZQhjld0pl-L8kHolJx7KGfTjQSegANUPg"
]
}
2.9.2 200 POST Assertion Response
Property | Type | Required | Description |
---|---|---|---|
status |
Status | Yes | The Status object describing the success or failure of the request. |
{
"status": {
"error": null,
"statusCode": 200,
"statusText": "OK"
}
}
2.9.3 200 GET Profile Response
Property | Type | Required | Description |
---|---|---|---|
status |
Status | Yes | The Status object describing the success or failure of the request. |
profile |
Profile | Yes | The matching Profile. |
{
"status": {
"error": null,
"statusCode": 200,
"statusText": "OK"
},
"profile": {
"@context": "https://w3id.org/openbadges/v2",
"id": "https://host.example.com/profile/12345",
"type": "Profile",
"name": "John Appleseed ",
"url": "https://example.com",
"email": "john@example.com"
}
}
2.9.4 200 POST Profile Response
Property | Type | Required | Description |
---|---|---|---|
status |
Status | Yes | The Status object describing the success or failure of the request. |
profile |
Profile | Yes | The updated Profile. |
{
"status": {
"error": null,
"statusCode": 200,
"statusText": "OK"
},
"profile": {
"@context": "https://w3id.org/openbadges/v2",
"id": "https://host.example.com/profile/12345",
"type": "Profile",
"name": "John Appleseed ",
"url": "https://example.com",
"email": "john@example.com"
}
}
2.9.5 400 Response
{
"status": {
"error": "Additional information regarding the error in human readable format.",
"statusCode": 400,
"statusText": "BAD_REQUEST"
}
}
Allowed values for the statusText property by endpoint:
- POST /assertions
- REQUEST_VALIDATION_ERROR (data validation of the request failed)
- RECIPIENT_PROFILE_MISMATCH (profile match failed)
- INVALID_BADGE (badge validation failed)
- BAD_REQUEST (all other errors)
- GET /assertions
- REQUEST_VALIDATION_ERROR (data validation of the request failed)
- BAD_REQUEST (all other errors)
- POST /profile
- REQUEST_VALIDATION_ERROR (data validation of the request failed)
- BAD_REQUEST (all other errors)
2.9.6 401 Response
{
"status": {
"error": "Additional information regarding the error in human readable format.",
"statusCode": 401,
"statusText": "UNAUTHENTICATED"
}
}
PERMISSION_DENIED is another acceptable value for statusText in the event that the request was authenticated but the scope does not include the requested resource.
2.9.7 404 Response
{
"status": {
"error": null,
"statusCode": 404,
"statusText": "NOT_FOUND"
}
}
2.9.8 405 Response
{
"status": {
"error": "Additional information regarding the error in human readable format.",
"statusCode": 405,
"statusText": "METHOD_NOT_ALLOWED"
}
}
A. Handling Null Values
This standard allows the use of the JSON null
data type, and empty arrays
such as []
in serialized JSON. Your code should be designed to deserialize
JSON with null values and empty arrays even if your code does not serialize them.
B. Data Types
The following primitive data types are referenced in this standard.
- DateTime - the date/time (using the [ISO8601] format
- Integer - the integer data-type
- String - normalized string
- URI - absolute or relative URI
C. Revision History
This section is non-normative.
C.1 Version History
Version No. | Document Version | Release Date | Comments |
---|---|---|---|
Version 2.1 IMS Candidate Final Public | 4 | October 25, 2021 | Fixed a number of specification and documentation issues. |
Version 2.1 IMS Candidate Final Public | 3 | October 7, 2020 | Releasing as Candidate Final Public. |
Version 2.1 IMS Candidate Final | 2 | January 24, 2020 | Second coordinated release. |
v2.1 Candidate Final | 1 | August 29, 2019 | First release of the Candidate Final specification. |
v2.1 Final | 1 | November 27, 2023 | Open Badges 2.1 Final release. |
D. References
D.1 Normative references
- [ISO8601]
- Representation of dates and times. ISO 8601:2004.. International Organization for Standardization (ISO). 2004. ISO 8601:2004. URL: http://www.iso.org/iso/catalogue_detail?csnumber=40874
- [json-ld11]
- JSON-LD 1.1. Gregg Kellogg; Pierre-Antoine Champin; Dave Longley. W3C. 16 July 2020. W3C Recommendation. URL: https://www.w3.org/TR/json-ld11/
- [OB-20]
- Open Badges v2.0. Otto, Nate; Bohrer, Jeff; Cook, Timothy; Gylling, Markus; Hripak, Alexander; Pitcher, Justin. IMS Global Learning Consortium. April 2018. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p0/
- [OB-21]
- Open Badges Specification v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p1/
- [OB-CERT-21]
- Open Badges Conformance and Certification Guide v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://www.imsglobal.org/spec/ob/v2p1/cert/
- [OB-JSON-21]
- JSON Schema Files for Open Badges Badge Connect(TM) API v2.1. Jeff Bohrer; Andy Miller. IMS Global Learning Consortium. November 27, 2023. IMS Final Release. URL: https://purl.imsglobal.org/spec/ob/v2p1/schema/json/
- [OPENAPIS]
- OpenAPI Specification. Darrell Miller; Jeremy Whitlock; Marsh Gardiner; Mike Ralphson; Ron Ratovsky; Uri Sarid; Tony Tam; Jason Harmon. OpenAPI Initiative. URL: https://www.openapis.org/
- [RFC2119]
- Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
- [RFC5785]
- Defining Well-Known Uniform Resource Identifiers (URIs). M. Nottingham; E. Hammer-Lahav. IETF. April 2010. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc5785
- [RFC6749]
- The OAuth 2.0 Authorization Framework. D. Hardt, Ed.. IETF. October 2012. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc6749
- [RFC7009]
- OAuth 2.0 Token Revocation. T. Lodderstedt, Ed.; S. Dronia; M. Scurtescu. IETF. August 2013. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7009
- [RFC7515]
- JSON Web Signature (JWS). M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7515
- [RFC7591]
- OAuth 2.0 Dynamic Client Registration Protocol. J. Richer, Ed.; M. Jones; J. Bradley; M. Machulak; P. Hunt. IETF. July 2015. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc7591
- [SEC-10]
- IMS Global Security Framework v1.0. C. Smythe; C. Vervoort; M. McKell; N. Mills. IMS Global Learning Consortium. April 2019. IMS Final Release. URL: https://www.imsglobal.org/spec/security/v1p0/
E. List of Contributors
The following individuals contributed to the development of this document:
Name | Organization | Role |
---|---|---|
Alexander Hripak | Credly | Editor |
Sara Arjona | Moodle | |
Jeff Bohrer | IMS Global | |
Viktor Haag | D2L | |
Takahiro Hata | Digital Knowledge EdTech Lab | |
Chris Houston | eLumen | |
Mark Leuba | IMS Global | |
Andy Miller | IMS Global | |
Omid Mufeed | Digitalme | |
Nate Otto | Concentric Sky | |
Justin Pitcher | Campus Labs | |
Alex Reis | D2L |