1EdTech Security Framework v1.1

1EdTech Security Framework

1EdTech Final Release
Version 1.1
1EdTech Final Release
Date Issued: July 19th, 2021
Status: This document is made available for adoption by the public community at large.
This version: https://www.imsglobal.org/spec/security/v1p1/
Latest version: https://www.imsglobal.org/spec/security/latest/
Errata: https://www.imsglobal.org/spec/security/v1p1/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 to the 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 web page: http://www.imsglobal.org/ipr/imsipr_policyFinal.pdf.

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.

© 2021 1EdTech Consortium, Inc. All Rights Reserved.

Trademark information: http://www.imsglobal.org/copyright.html

Abstract

1EdTech has created, is creating, and will create, service-oriented and message-exchange interoperability specifications. These specifications recommend or require a number of different security patterns: for example, the use of OAuth 1.0 based message signing, OAuth 2 based authentication and authorization, and so forth. In this document, 1EdTech defines a set of patterns for security that all of its specifications SHOULD use (only in special circumstances will 1EdTech consider exceptions). These security patterns are based upon the appropriate standards and specifications published by other organizations: for example the Internet Engineering Task Force (IETF) and its Requests For Comments (RFCs). The aim is to make use of the appropriate solutions and best practices already adopted in the IT sector as a whole.

This security framework has three basic patterns for adoption:

  • Use of the OAuth 2.0 Client Credential Grant mechanism to secure web services between trusted systems (this MAY make use of JSON Web Tokens, JWT, for the access tokens);
  • Use of the OAuth 2.0 Authorization Code Grant mechanism to secure web services between systems where there is no pre-established trust relationship (this MAY make use of JWT for the access tokens);
  • Use of OpenID Connect with JWT-based message exchanges to secure browser-instigated exchanges between a tool and the launching platform.

All new 1EdTech specifications MUST review the security patterns defined herein and adopt those that are suitable. 1EdTech MAY revise specifications that have already been published to align with these security patterns. Furthermore, the functionality addressed in this framework will itself will be extended in response to the new and changing requirements from the suite of published 1EdTech specifications.

This document is written for use by:

  • Architects who wish to understand the security framework for the 1EdTech Ecosystem;
  • Developers who have to implement a 1EdTech specification that uses one or more of the security patterns described in this framework;
  • Users who need to understand the security capabilities of the 1EdTech certified solutions they do, or want to, deploy.

1. Introduction

1.1 Scope and Context

Adopters of 1EdTech specifications will refer to this document with respect to the security approaches they MUST use. The aim is to require all of the 1EdTech specifications to use a common security framework. Use of a common security framework promotes a consistent and compatible implementation requirement that simplifies adoption when more than one 1EdTech specification is being implemented.

The target readers for this document are:

  • Learning Systems Architects - the people who are responsible for the definition and design of systems, applications and tools that are to be used to support teaching and learning. This includes those who are responsible for issuing, and responding to, Tender documents. The Security Framework provides the architectural context as well as the implementation detail;
  • Developers of 1EdTech specifications - people who are developing new specification or new versions of specification. They will select and cite the relevant parts of the Security Framework in the specifications. When appropriate they will raise issues requiring clarifications and, perhaps, the addition of new features to the Security Framework;
  • Product developers implementing 1EdTech specifications - people who are adding the functionality defined in the 1EdTech specification(s) to their products. They will make use of the Security Framework document to obtain all of the relevant details that are cited and summarised in the relevant 1EdTech specification.

All 1EdTech service-based specifications MUST make reference to this document. The 1EdTech service specifications will cite appropriate sections of this document. In some cases, 1EdTech specifications MAY contain exceptions to the recommendations made in this document. These exceptions MUST be explained and justified in the 1EdTech specification citing this document. The Best Practice and/or Implementation Guide documents for the relevant 1EdTech specification MUST provide further explanation to implementers regarding the manner in which they are to implement security requirements in the context of that specification.

While creating this document the core principle has been to adopt, and adapt, the relevant security standards, specifications and best practices that are used in other market sectors. This has resulted in the following baseline:

  • OAuth 2 Authorization (from the IETF) has broad world-wide adoption as is now the de facto standard for secure web services;
  • OpenID Connect (from the OpenID Foundation) has broad adoption for providing identity verification on top of the OAuth 2 protocol.

A number of changes have been made when adopting a third-party standards/specification (see the summary presented in the Appendix. The justifications for these changes are to:

  • Remove implementation uncertainty i.e. to make an optional feature either required or prohibited. Typically, this is when a feature is described as MAY or SHOULD and making it MUST or MUST NOT;
  • Ensure the Security Framework is self-consistent. The framework is based upon many standards from several organizations and so it is important that terms, definitions, etc. are consistently used;
  • Ensure the Security Framework is applicable to all of the 1EdTech service specifications and facilitates work flows that combine more than one 1EdTech specification. One framework to rule them all!

1.2 Differences Between Versions 1.0 and 1.1

In version 1.1 several functional additions have been made due to the requirements from new 1EdTech specifications. These additions are:

  • Support for access token refresh as part of the OAuth 2 Authorisation Code Grant work flow;
  • Support for access token revocation (using [RFC7009] as part of the OAuth 2 Client Credentials;
  • Support for access token and/or refresh token revocation (using [RFC7009] as part of the OAuth 2 Authorisation Code Grant work-flow;
  • Support for dynamic client registration to simplify the use of OAuth 2 using [RFC7591] and [RFC7592];
  • Support for dynamic client registration to simplify the use of OpenID Connect [OPENID-DCR] and [OPENID-DIS].

Also, several clarifications have been made. These clarifications are:

  • It has been noted that an HTTP POST request MUST used to obtain an access token;
  • When obtaining an access token the grant type and scopes are placed in the request body and NOT sent as query parameters;
  • The scope parameter has been added as a REQUIRED value in the redirect message within the Authorization Code Grant exchange.
  • In JSON Web tokens an array with a single value MUST be encoded as an array;
  • The preferred list of signing algorithms for use with JSON Web Tokens has been defined. This is the list of signing algorithms that SHOULD be supported and MUST be used.

1.3 Recommendations for Migrating from Version 1.0 to 1.1

Apart from a few bug fixes and corrections the new functionality added in version 1.1 is backwards compatible with version 1.0. Therefore, migration from version 1.0 to 1.1 SHOULD occur as part of the natural revision cycle on a per 1EdTech specification basis. The recommendations for migration to version 1.1 are:

  • For 1EdTech specifications that cite use of the Security Framework 1.0 and which do not make use of any of the new features in version 1.1, migration will take the form of a documentation PATCH revision in which all references to version 1.0 are replaced by reference to 1.1. 1EdTech Staff will be responsible for such revisions;
  • For 1EdTech specifications that cite use of the Security Framework 1.0 and which make use of the new features in version 1.1, migration will take the form of a MINOR specification revision. The timing of this revision will be determined by the relevant Product Steering Committee (PSC) and the work will be undertaken by the new Working Group. There is no requirement to revise a specification to complete this security framework migration only. As part of the 1EdTech specification development process, the 1EdTech Security Committee will review the new version and confirm compliance with the Security Framework.

Each year, the 1EdTech Security Committee publish their annual audit report. This audit report contains the details about which version of the Security Framework is used by an 1EdTech specification and the corresponding recommendations and actions required to be undertaken with respect to the specification. Therefore, the audit report enables tracking of the progress of the migration from version 1.0 to 1.1 of the Security Framework.

1.4 Structure of this Document

The structure of the rest of this document is:

2. Security Architecture Description of the security architectures that are enabled using the Security Framework.
3. Transport Security Statement of the requirement to use the Transport Layer Security (TLS) to secure the HTTP exchange.
4. Securing Web services Description of when and how the OAuth 2.0 standard is to be used in the context of 1EdTech services.
5. Message Security and Message Signing Description of when and how the OpenID Connect specification is to be used in the context of 1EdTech services.
6. Key Management Description of how public and private key management should be achieved in the context of 1EdTech services.
7. Best Practice Recommendations The best practice recommendations when enabling the security mechanisms in the context of the 1EdTech services.
Appendix A - Service Description Documents Using OpenAPI An example of supplying a Service Description Document using the OpenAPI files created by 1EdTech as part of the development of an 1EdTech service-based specification. A new Appendix added in version 1.1.
Appendix B – Summary of Changes Made with Respect to Core Standards Collation of the various changes that have been to the various open standards and specifications when they are used in the context of 1EdTech services. A new Appendix added in version 1.1.
Appendix C – Relevant standards A brief summary, and link to the actual standard, of all of the standards upon which the Security Framework is based.
Appendix D – Revision History History of the various published versions of this document. This includes details of the changes made with respect to the previously published version.
Appendix E – References The details of the set of documents cited within this document.
Appendix F – List of Contributors The people who were responsible for the creation of this document.

1.5 Conformance Statements

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", "NOT RECOMMENDED", "NOT REQUIRED", "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.6 Terminology

The terminology definitions in this section, are a normative portion of this specification, imposing requirements upon implementations. All the capitalized words in the text of this specification, such as "Issuer Identifier", refer to these defined terms. Whenever readers encounter them, they must follow their definitions found in this section.

Note that the term "Client" is used as defined by OAuth 2.0. Therefore, communication being secured is between a Platform and a Consumer. Depending on the specific exchange choreography either of these could be the Client. From the perspective of a service either the Platform or the Consumer could initiate the communication exchange.

For more background on some of the terminology used, see Internet Security Glossary, Version 2 [RFC4949], ISO/IEC 29115 Entity Authentication Assurance [ISO29115], and ITU-T X.1252 [ITU-X1252].

This specification defines the following terms:

Authentication
Process used to achieve sufficient confidence in the binding between an entity and the presented Identity.
Authorization
The process to determine whether an authenticated user can have access to particular resources.
Claim
Piece of information asserted about an entity.
Consumer
An entity for which an end user gains access through a Platform. The Consumer may make use of, or provide services to, the Platform.
ID Token
JWT that contains Claims about the Authentication event. It MAY contain other Claims.
Identifier
Value that uniquely characterizes an entity in a specific context.
Identity
Set of attributes related to an entity.
Issuer
Entity that issues a set of Claims. The Issuer is the entity that starts an information exchange and as such could be either a Platform or a Consumer.
Issuer Identifier
Verifiable identifier for an Issuer. An Issuer Identifier is a case-sensitive URL, using the HTTPS scheme, that contains scheme, host, and optionally, port number, and path components, and no query or fragment components.
Message
Request or a response between a Consumer and a Platform.
Platform
An entity through which an end user interacts to gain access to some remotely launched Tool or a Consumer. The Platform may make use of, or provide services to, the Tool or may provide services to the Consumer.
Private Key
The private key in the private-public key pair. This is the secret key that is used by the Issuer, of a message, to sign the JWT using the JSON Web Signature [RFC7515].
Public Key
The public key in the private-public key pair. This is the key used at the receiving system to authenticate the message and confirm it has not been altered during transmission.
Relying Party
OAuth 2.0 Client application requiring End-User Authentication and Claims from an OpenID Provider.
Service Description Document
This is the machine readable document that contains the description of the service features supported by the Provider/Platform. This is an OpenAPI 3.0 (JSON) [OAS3P0] structured document.
Subject Identifier
Locally unique and never-reassigned identifier within the Issuer for the end user, which is intended to be consumed by the Consumer. This identifier MUST be the same as the Issuer's User ID for that end user.
Tool
An entity which has been launched by a Platform. The Tool may make use of, or provide services to, the Platform.
Validation
Process intended to establish the soundness or correctness of a construct in the context of the original requirement.
Verification
Process intended to test or prove the truth or accuracy of a fact or value.
Voluntary Claim
Claim specified by the Consumer as being useful but not essential for the specific task requested by the end user.

This specification also uses the terms:

"Client", "Client Authentication", "Client Identifier" and "Scope"
As defined by OAuth 2.0 [RFC6749].
"Claim List", "Claim Name", "Claim Value", "JSON Web Token (JWT)", "JWT Claims Set", "Nested JWT", and "String or URI"
As defined by JSON Web Token [RFC7519]
"Code Verifier", "Code Challenge" and "Code Challenge Method"
As defined by Proof Key for Code Exchange [RFC7636]
"Header Parameter" and "JOSE Header"
As defined by JSON Web Signature (JWS)[RFC7515]
"User Agent"
As defined by [RFC2616].

1.7 Acronyms

CSRF
Cross-Site Request Forgery
DCR
Dynamic Client Registration
HTTP
Hypertext Transport Protocol
HTTPS
Hypertext Transport Protocol Secure
IANA
Internet Assigned Number Authority
IETF
Internet Engineering Task Force
ISO
International Standards Organization
ITU
International Telecommunications Union
JOSE
JSON Object Signing and Encryption
JSON
Java Script Object Notation
JWA
JSON Web Algorithms
JWE
JSON Web Encryption
JWK
JSON Web Key
JWS
JSON Web Signature
JWT
JSON Web Token
LTI
Learning Tools Interoperability
MAC
Message Authentication Code
PKCE
Proof Key for Code Exchange
PSC
Product Steering Committee
RFC
Request for Comments
RSA
Rivest–Shamir–Adleman
SDD
Service Description Document
SSL
Secure Sockets Layer
TLS
Transport Layer Security
URL
Uniform Resource Locator

2. Security Architecture

All of the 1EdTech specifications define the syntax and semantics of the data that is to be exchanged. Some of the 1EdTech specifications also define the protocol for the exchange of that data. These are the 1EdTech service specifications. In most cases the protocols used to exchange the data MUST also protect the data i.e. provide secure data exchange. This includes authentication, authorization, encryption and dynamic client registration.

2.1 Web Services-based Architectures

Some 1EdTech specifications describe a set of web service calls that can occur between a service consumer (Consumer) and a service provider (Platform). Typically a service call occurs between a Consumer and Platform when one 'pulls' data from the other (using an HTTP GET) or 'pushes' data (using HTTP PUT or POST) to the other. Figure 1 is a schematic representation of how this security framework expects a Consumer and Platform to perform these service calls.

Figure 1 Web services architecture.

Each 1EdTech specification will define how the Consumer and Platform will exchange information. When a service call MUST be done securely, the sender MUST use the methods described in this framework to secure the data transfer. This document defines how to achieve the "Authentication and Authorization" portion of the protocol represented in Figure 1 and how each data exchange will use this information. The set of endpoints identified in Figure 1 are:

  • 'A' - set of endpoints exposed by the Service Provider API as defined by the relevant 1EdTech service specification;
  • 'X' - the endpoint used to discover the available characteristics of the Service Provider including the Registration URL i.e. endpoint labelled 'J' (added as part of version 1.1). Support of this endpoint is REQUIRED;
  • 'I' - OAuth2 Authorization endpoint for obtaining the access token, refreshing an access token and revoking an access token. Support of this endpoint is REQUIRED when using OAuth 2;
  • 'J' - Client Registration endpoint (added as part of version 1.1). Support of this endpoint is REQUIRED when using Dynamic Client Registration;
  • 'K' - the set of Client Configuration endpoints (added as part of version 1.1). Support of these endpoints is OPTIONAL when using Client Registration.

The "Authentication and Authorization" portion of the exchange is based on the OAuth 2.0 protocol flow (as defined in [RFC6749] section 1.2). Sequences 'A' - 'D' in Figure 2 shows the abstract protocol flow for acquiring the needed authorization information, and sequences 'E' - 'F' show the flow of using the authorization information to perform the service call. Note that in Figure 2, the Client, as defined by OAuth 2.0, could be either the Platform or Consumer depending on which entity initiates the exchange.

Figure 2 Web services abstract protocol flow.

In OAuth 2.0 there are four functional components in the authentication and authorization flow:

Consumer (Client). The system, application, or tool that requires access to the corresponding resource via a specific endpoint or set of endpoints.

Resource Owner. The system, application, or tool that owns the resource located at a specific endpoint or set of endpoints and which can provide permission to obtain access to that resource.

Authorization Server. The system responsible for allocating the appropriate access authorization using the authentication information supplied to it by the Client.

Resource Server. The system, application, or tool that makes the corresponding resource available via the specific endpoint or set of endpoints and that supports the defined authorization mechanism.

In general, a Consumer may obtain authorization through three phases:

  1. Obtain authorization to resource (Phase 1) - denoted by sequence 'A' and 'B' in Figure 2.

  2. Obtain the access information from the authorization server (Phase 2) - denoted by sequence 'C' and 'D' in the Figure 2. If a system does not support Phase 1, the required permissions information SHOULD be obtained via some out-of-band process.

  3. Obtain access to the resource (Phase 3) - denoted by sequence 'E' and 'F' in the figure. If a system does not support Phase 2, then the required access information SHOULD be obtained via some out-of-band process.

In cases where there is an established trust between the Clients and Platforms, only Phases 2 and 3 will be used, relying on shared credentials obtained out-of-band (see OAuth 2.0 [RFC6749] Section 4.4). In cases where there is no pre-established trust relationship all three Phases MUST be used.

2.2 Non-Web Services-based Architectures

In the case where 1EdTech has defined a non-web services based standard, the specification will describe the set of messages that can occur between a Platform and a Tool. In scenarios where the message exchange is vulnerable (for example, when launching from a web browser), the messages will be signed. This signing MAY include data derived from the identity-based authentication. For 1EdTech specifications using a non-web services approach, Figure 3 shows a schematic representation of this security framework.

Figure 3 Non-web services architecture.

The 1EdTech specification defines how a Tool can transform the messages exchanged between the Platform and the Tool (including a user's browser-based interaction) into a Tool-based experience. This document defines how to achieve Authentication and Authorization using a separate set of message exchanges between Platform and Tool and how to encode the authorization and authentication information in JWT-based message signing of these message exchanges. The authorization and authentication process uses an authorization server which MAY be a system independent of the Platform or MAY be endpoints hosted by the Platform.

3. Transport Security

Senders and receivers of data should encrypt the data to ensure that third parties cannot read the data in transit (for example, by sniffing packets).

Therefore Platforms and Consumers MUST send all requests and responses using Transport Layer Security (TLS). Exchange of the signed certificates for endpoints between Platforms and Consumers is beyond the scope of this specification. 1EdTech advises implementers to refer to the various third-party certificate-signing services in order to obtain signed certificates.

Implementers MUST use TLS 1.2 (see [RFC5246]) and/or TLS 1.3 (see [RFC8446]). Note that [RFC8446] obsoletes [RFC5246], therefore it is RECOMMENDED that [RFC8446] is used. Implementers MUST NOT use Secure Sockets Layer (SSL).

4. Securing Web Services

4.1 Using OAuth 2.0 Client-Credentials Grant

When there is an established trust relationship between the resource owner, the resource server and the system requiring access to the resource(s), the approach shown in Figure 4 MUST be used for the web services. It is assumed that the OAuth 2 Client is the Consumer and the Resource Server the Platform. Authentication and Authorization requires the use of OAuth 2.0 bearer tokens, obtained using the mechanism described in Section 4.4 of [RFC6749].

Figure 4 OAuth 2 client credentials based resource access.

Making a secured web service request comprises two steps:

  1. Obtain an access token by sending a request to the Platform's OAuth 2 Access Token service endpoint (as in flow 'C/D' in the figure);

  2. Include the access token in the Authorization header of service request messages (as in flow 'E/F' in the figure).

Once obtained, the Consumer can freely re-use the access token up until the token's expiry time, so that the Consumer need not repeat step 'C' for every service request. The specific, appropriate mechanism for obtaining the set of credentials is not within the scope of this document.

In 1EdTech service specifications, scopes, as defined in [RFC6749], MUST be used when requesting an access token. The authorization server is responsible for validating the scopes identified in the request and the response MUST include a scope parameter which confirms this list or comprises a subset of the services requested. The Authorization Server may refuse to provide an access token and so MUST return an error response.

Consumers MUST use the OAuth 2.0 Client Credentials grant type. In this grant type, the Consumer can request an access token using only its credentials (using its consumer key and secret information) in these cases:

  • The Consumer is requesting access to the protected resources under its control;

  • The Consumer is requesting access to resources owned by another resource owner that has previously arranged this access permission with the authorization server.

In this approach, the Consumer issues a Consumer authentication request and receives an access token in response. Section 5 of [RFC6749] defines the issuing of an access token. To obtain an access token for 1EdTech service access requires four pieces of configuration information:

Key. The public identifier for the communication exchange (this is also referred to as the application ID).

Secret. The shared secret for the communication exchange (this is also referred to as the application secret).

List of Scopes. The list of scopes that identify the set of endpoints for which access permission is being requested.

OAuth 2 Access Token Service Endpoint. The endpoint from which the approved, requesting Consumer can obtain the access token.

Requests for an access token MUST use HTTP POST over TLS. The Consumer MUST use its key and secret with the HTTP Basic Authentication method (as described in [RFC2617]) for this request and MUST NOT put the key and secret into the request body.

For client credentials based 1EdTech Web Services, the set of parameters (Section 4.4 of [RFC6749]) used to request an access token are:

grant_type
REQUIRED. Value MUST be set to client_credentials.
scope
REQUIRED. The scope of the access request.

An example of the request message is shown below in which three scopes (scopename1, scopename2 and scopenamex) are identified:


POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Length: <length>
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&scope=scopename1%20scopename2%20scopenamex
    

The recommended naming convention to be used for scopes is described in Scope Naming Conventions of this document. The request parameters MUST be placed in the request body and MUST NOT be sent as URL query parameters.

NOTE: In [RFC6749] Section 3.2, it states that requests for an access token MUST use a POST request.

If the authorization service successfully grants this request (see Section 5.1 in [RFC6749] for the detailed description), it responds with an HTTP 200 OK response containing the access token and its expiry lifetime (1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens) and confirms the set of scopes supported by this access token:


HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token" : "2YotnFZFEjr1zCsicMWpAA",
    "token_type" : "bearer",
    "expires_in" : 3600,
    "scope" : "scopename1 scopename2 scopenamex"    
}        

The Consumer utilizes the access token to authenticate with the resource using the HTTP Authorization request header field [RFC2617] with an authentication scheme defined by the specification of the access token type used, such as [RFC6750]. For example, with a bearer-type token, a resource retrieval request uses this form:


GET /resource/1 HTTP/1.1
Host: provider.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
      

The authorization server MAY decide not to issue an access token: this could be because the request scopes are invalid, the credentials from the client may be invalid, etc. In this case the authorization server MUST return an error message (see Section 5.2 in [RFC6749] for the detailed description) with an HTTP 400 (Bad Request) status code. An example of the error response message (when the requested scope is invalid) is:


HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "error" : "invalid_scope"    
}
      		

4.1.1 Using JSON Web Tokens with OAuth 2.0 Client-Credentials Grant

In this approach, a Consumer generates a JWT [RFC7519] bearer token as a means for authentication in requesting an OAuth 2.0 access token, which it can then use to authorize requests to services as per [RFC7523].

The JWT payload MUST contain at least the following Claims:

Claim Description
iss A unique identifier for the entity that issued the JWT
sub "client_id" of the OAuth Consumer
aud Authorization server identifier (s)
iat Timestamp for when the JWT was created
exp Timestamp for when the JWT should be treated as having expired (after allowing a margin for clock skew)
jti A unique (potentially reusable) identifier for the token

{
    "iss" : "tool.com",
    "sub" : "www.example.com",
    "aud" : ["https://www.example.com/lti/auth/token"],
    "iat" : "1485907200",
    "exp" : "1485907500",
    "jti" : "29f90c047a44b2ece73d00a09364d49b"
}        
      

The aud Claim MUST contain a value that identifies the authorization server as an intended audience. The Consumer MAY use the token endpoint URL of the authorization server as a value for an aud element to identify the authorization server as an intended audience of the JWT. The authorization server MUST reject any JWT that does not contain its own identity as the intended audience. This information MUST be sent as an array even when there is only one value.

The iat Claim MUST be the time at which the Consumer generated the JWT.

The exp Claim MUST be an absolute expiry time for the message (typically five minutes after the iat timestamp); the Consumer MUST honor this expiry time, though it MAY also choose to expire the JWT at an earlier time (but no earlier than the iat value). This exp timestamp SHOULD also indicate when the jti value expires and could be re-used.

The Consumer MAY include other top-level Claims in the JWT and, if it does so, the authorization server MAY ignore them.

The above JSON structure represents the first, payload element of the JWT. The Consumer MUST also add a second, header element, referred to as the JSON Object Signing and Encryption (JOSE) header, that defines the algorithm it used to sign the token.


{
    "typ" : "JWT",
    "alg" : "RS256"
}
      

The approved list of algorithms that MUST be used for JWT signing, and permitted as the value of alg is given in the Best Practices.

The Consumer MUST generate a third, signature element by applying the algorithm to the contents of both the header and payload elements (see [RFC7515] for how to create a JSON Web Signature, JWS). The Consumer then forms the value of the JWT by separately base-64 encoding each of the three elements and concatenating them with a period (.) as a separator character i.e.


JWT = base64_encode(JOSE Header).base64_encode(Claim Set Payload).base64_encode(JWS Signature)        
      

creating a JWT of (line breaks added for clarity):


eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJpc3MiOiJ0b29sLmNvbSIsInN1YiI6Ind3dy5leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3Lm
V4YW1wbGUuY29tL2x0aS9hdXRoL3Rva2VuIiwiaWF0IjoiMTQ4NTkwNzIwMCIsImV4cCI6IjE0ODU5MDc1
MDAiLCJqdGkiOiIyOWY5MGMwNDdhNDRiMmVjZTczZDAwYTA5MzY0ZDQ5YiJ9
.liArqLDIF-xGcCu8ythy0HlzntxwZ90AYTnwH-daCQQ        
      

The Consumer's resulting authorization request uses the following POST parameters:

  • grant_type=client_credentials

  • client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer

  • client_assertion= the Consumer's generated JWT

  • scope=https://purl.imsglobal.org/spec/lti-ags/scope/lineitem https://purl.imsglobal.org/spec/lti-ags/scope/result/read

This leads to a request with the following form (with line breaks for clarity):


POST /lti/auth/token HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=client_credentials&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJpc3MiOiJ0b29sLmNvbSIsInN1YiI6Ind3dy5leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL2x0aS9hdXRoL3R
va2VuIiwiaWF0IjoiMTQ4NTkwNzIwMCIsImV4cCI6IjE0ODU5MDc1MDAiLCJqdGkiOiIyOWY5MGMwNDdhNDRiMmVjZTczZDAwYTA5MzY0ZDQ5YiJ9
.liArqLDIF-xGcCu8ythy0HlzntxwZ90AYTnwH-daCQQ
&scope=http%3A%2F%2Fimsglobal.org%2Fspec%2Flti-ags%2Fscope%2Flineitem%20http%3A%2F%2Fimsglobal.org%2Fspec%2Flti-ags%2Fscope%2Fresult%2Fread        

The authorization server decodes the JWT and MUST validate the values for the iss, sub, exp, aud and jti claims, followed by verifying the signature. If it finds the request to be a valid, it generates and returns an access token, with a response of this form:


HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token" : "dkj4985kjaIAJDJ89kl8rkn5",
    "token_type" : "bearer",
    "expires_in" : 3600,
    "scope" : "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem https://purl.imsglobal.org/spec/lti-ags/scope/result/read"    
}        

As per [RFC7519] the token MUST ONLY contain ASCII characters (0x20-0x7A) and SHOULD be at least 15 characters in length. The token MAY be a JWT (see below). 1EdTech recommends a default expiry time of 1 hour (3600 seconds). The bearer of the token can use it until the token expires (as evidenced by a failed request) but 1EdTech recommends that a Consumer manages tokens such that once they have expired (allowing for clock skew between the systems), it requests a new one when needed.

4.1.1.1 Using a JWT as an Access Token

Consumers SHOULD treat the access token returned by the authorization server as an opaque string. Any meaning that the token may have is relevant only to the authorization server and resource provider. If a resource provider does not wish to manage access tokens, it can use a JWT to encapsulate the details of the token so that the bearer provides the details with each service request for verification.

Following from the above example, this might be the access JWT token's payload:


{
    "sub" : "www.example.com",
    "iat" : "1485907200",
    "exp" : "1485907500",
    "imsglobal.org.security.scope" : "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem https://purl.imsglobal.org/spec/lti-ags/scope/result/read"    
}          

This might be the JWT's header:


{
    "typ" : "JWT",
    "alg" : "RS256"
}          

The approved list of algorithms that MUST be used for JWT signing, and permitted as the value of alg is given in the Best Practices.

After signing, this would create the JWT:


eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3d3cuZXhhbXBsZS5jb20iLCJpYXQiOiIxNDg1OTA3MjAwIiwiZXhwIjoiMTQ4NTkwNzUwMCIsImltc2dsb2JhbC5vcmcuc2VjdXJpdHkuc2NvcGUiOiJMdGlMaW5rU2V0dGluZ3MgU2NvcmUuaXRlbS5QVVQifQ.UWCuoD05KDYVQHEcciTV88YYtWWMwgb3sTbrjwxGBZA          
        

Thus, the authorization server might return this access token in a response like this:


HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token" : "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ3d3cuZXhhbXBsZS5jb20iLCJpYXQiOiIxNDg1OTA3MjAwIiwiZXhwIjoiMTQ4NTkwNzUwMCIsImltc2dsb2JhbC5vcmcuc2VjdXJpdHkuc2NvcGUiOiJMdGlMaW5rU2V0dGluZ3MgU2NvcmUuaXRlbS5QVVQifQ.UWCuoD05KDYVQHEcciTV88YYtWWMwgb3sTbrjwxGBZA",
    "token_type" : "bearer",
    "expires_in" : 3600,
    "scope" : "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem https://purl.imsglobal.org/spec/lti-ags/scope/result/read"
}          
        

When the resource provider receives a service request with this access token, it can verify the signature and extract the details of the validity of the request from the JWT before proceeding to process the request.

4.1.2 Token Revocation

There may be deployments in which revocation of an access token is useful. The Token Revocation process is based upon [RFC7009]. The Consumer requests the revocation of a particular token by making an HTTP POST request (using TLS) to the token revocation endpoint URL.

The client constructs the request by including the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body:

token
REQUIRED. The token that the client wants to get revoked.
token_type_hint
REQUIRED. MUST be set to access_token.

An example of the request message is shown below:


POST /revoke HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

token=45ghiukldjahdnhzdauz&token_type_hint=access_token
    

The authorization server responds with HTTP status code 200 if the token has been revoked successfully or if the client submitted an invalid token.

When the request for revocation is rejected the error presentation conforms to the definition in Section 5.2 of [RFC6749]. The following additional error code is defined for the token revocation endpoint:

unsupported_token_type
The authorization server does not support the revocation of the presented token type. That is, the client tried to revoke an access token on a server not supporting this feature.

4.2 Using OAuth 2.0 Authorization Code Grant

In scenarios where the learner or another third party is the resource owner, there will not be a pre-established trust relationship. Therefore the client credentials approach is insufficient. Instead 1EdTech RECOMMEND the use of OAuth 2.0 Authorization Code Grant. Figure 5 shows the assumed system architecture when the resource owner is required to provide explicit permission for access to a resource. It is assumed that the OAuth 2 Client is the Consumer and the Resource Server the Platform. The User Agent could be a Browser. Authentication and Authorization requires the use of OAuth 2.0 bearer tokens, obtained using the mechanism described in Section 4.1 of [RFC6749].

Figure 5 OAuth 2 authorization code grant based resource access.

Making a secured web service request using authorization code grant comprises three steps:

  1. Obtain an authorization code using a choreography between the Consumer, User Agent, Resource Owner and Authorization Server (as in flow A/U/B in the figure);

  2. Obtain an access token by sending a request, using the previously obtained authorization code, to the Platform's OAuth 2 Access Token service endpoint (as in flow 'C/D' in the figure);

  3. Include the access token in the Authorization header of service request messages (as in flow 'E/F' in the figure).

Once obtained, the Consumer can freely re-use the access token up until the token's expiry time, so that the Consumer need not repeat step 'C' for every service request. Token refresh is also available and if adopted MUST be used as described in [RFC6749] Section 5.2

In 1EdTech service specifications, the state parameter, as defined in [RFC6749], MUST be used when requesting an access token. The state parameter is an opaque value used by the client to maintain state between the request and callback. The authorization server includes this value when redirecting the user-agent back to the client. This parameter MUST be used for preventing cross-site request forgery.

In 1EdTech service specifications, the scope parameter, as defined in [RFC6749], MUST be used when requesting an access token. The authorization server is responsible for validating the scopes identified in the request and the response MUST include a scope parameter which confirms this list or comprises a subset of the services requested. The Authorization Server may refuse to provide an access token and so MUST return an error response.

In the OAuth 2.0 Security Best Practices document [OAUTH2-SBP] the use of Proof Key for Code Exchange (PKCE) [RFC7636] is recommended in order to (with the help of the authorization server) detect and prevent attempts to inject (replay) authorization codes into the authorization response. When using 1EdTech specifications, PKCE MUST be used to protect Authorization Code Grant based access. The PKCE has two stages:

  • The Consumer MUST supply a code_challenge and code_challenge_method in the request for an authorization code. The authorization server is responsible for associating the code_challenge with the issued code;
  • The Consumer MUST supply the code_verifier in the Access Token Request, and the authorization server verifies the code_verifier.

For authorization code grant based 1EdTech Web Services, the set of parameters (Section 4.1 of [RFC6749]) used to request an authorization code are:

resonse_type
REQUIRED. Value MUST be set to code.
client_id
REQUIRED. The client identifier.
redirect_uri
OPTIONAL.
scope
REQUIRED. The scope of the access request.
state
REQUIRED. An opaque value used by the client to maintain state between the request and callback.
code_challenge
REQUIRED. This is BASE64URL-ENCODE(SHA256(ASCII(code_verifier))).
code_challenge_method
REQUIRED. This MUST have a value of S256 i.e. the SHA256 code verifier transformation method is used.

The Consumer initiates the flow by directing the resource owner’s user-agent to the authorization endpoint (flow (A) in Figure 5). All exchanges MUST use TLS. The Consumer includes its client identifier, requested scope, local state, and a redirection URI to which the authorization server will send the user-agent back once access is granted (or denied). For 1EdTech, the parameters scope, state, code_challenge and code_challenge_method MUST be used (code_challenge and code_challenge_method are required as part of the PKCE). All of the parameters MUST be sent in the request body and MUST NOT be sent as URL query parameters. An example of the request is shown below in which one scope (scopename1) is identified:


GET /authorize?response_type=code&client_id=s6BhdRkqt3&state=xyzjklabc&scope=scopename1&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challange_method=S256&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb HTTP/1.1
Host: server.example.com     
    

If the resource owner grants the access request, the authorization server issues an authorization code and delivers it to the Consumer by adding the specific parameters to the query component of the redirection URI (flow (B) in Figure 5. The parameters to be supplied are:

code
REQUIRED. The authorization code.
scope
REQUIRED. The authorized scope for the access request (this MAY be a subset of the scopes in the request).
state
REQUIRED. The opaque value supplied by the client to maintain state between the request and callback.

For example, the authorization server redirects the user-agent by sending the following HTTP response


      HTTP/1.1 302 Found
      Location: https://client.example.com/cb?code=SplxlOBeZQQYbYS6WxSbIA&state=xyzjklabc&scope=scopename1
    

This authorization code MUST be used only once. A lifetime for the authorization code of 600 seconds (10 minutes) is RECOMMENDED. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI.

If the resource owner denies the access request or if the request fails for reasons other than a missing or invalid redirection URI, the authorization server informs the client by adding the following parameters to the query component of the redirection URI. For example:


      HTTP/1.1 302 Found
      Location: https://client.example.com/cb?error=access_denied&state=xyzjklabc
    

The next step is use the authorization code to obtain the access token (flow (C) in Figure 5). Requests for an access token use an HTTP POST and TLS. The Consumer MUST use its key and secret with the HTTP Basic Authentication method (as described in [RFC2617]) for this request and MUST NOT put its key and secret into the request body. As REQUIRED by PKCE, the code verifier parameter MUST be supplied. Therefore for authorization code grant based 1EdTech Web Services, the set of parameters (Section 4.1 of [RFC6749]) used to request an access token are:

grant_type
REQUIRED. Value MUST be set to authorization_code.
code
REQUIRED. The authorization code received from the authorization server.
client_id
REQUIRED, if the client is not authenticating with the authorization server
redirect_uri
REQUIRED, if the redirect_uri parameter was included in the authorization request
scope
REQUIRED. The scope of the access request.
code_verifier
REQUIRED. Code verifier.

These parameters MUST be supplied in the request body and MUST NOT be supplied as URL query parameters. An example of the request message is shown below:


POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Length: <length>
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&scope=scopename1&redirect_uri=https%3A%2F%2Fclient%2Eexample%2Ecom%2Fcb&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
    

NOTE: In [RFC6749] Section 3.2, it states that requests for an access token MUST use a POST request.

If the authorization service successfully grants this request (see Section 5.1 in [RFC6749] for the detailed description), it responds with an HTTP 200 OK response (flow (D) in Figure 5 containing the access token and its expiry lifetime (1EdTech recommends a default expiry lifetime of 3600 seconds, one hour, for access tokens) and confirms the scopes:


HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token" : "2YotnFZFEjr1zCsicMWpAA",
    "token_type" : "bearer",
    "expires_in" : 3600,
    "scope" : scopename1,
    "refresh_token":"tGzv3JOkF0XG5Qx2TlKWIA"    
}        

The Consumer utilizes the access token to authenticate with the resource using the HTTP Authorization request header field [RFC2617] with an authentication scheme defined by the specification of the access token type used, such as [RFC6750]. For example, with a bearer-type token, a resource retrieval request uses this form (flow (E) in Figure 5:


GET /resource/1 HTTP/1.1
Host: provider.example.com
Authorization: Bearer 2YotnFZFEjr1zCsicMWpAA
      

The authorization server MAY decide not to issue an access token: this could be because the request scopes are invalid, the credentials from the client may be invalid, the PKCE code verifier value is invalid, etc. In this case the authorization server MUST return an error message (see Section 5.2 in [RFC6749] for the detailed description) with an HTTP 400 (Bad Request) status code. An example of the error response message (when the requested scope is invalid) is:


HTTP/1.1 400 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "error" : "invalid_scope"    
}
      

4.2.1 Using JSON Web Tokens with OAuth 2.0 Authorization Code Grant

In this approach, a Consumer generates a JWT [RFC7519] bearer token as a means for authentication in requesting an OAuth 2.0 access token, which it can then use to authorize requests to services as per [RFC7523]. This is similar to the approach for using JSON Web Tokens with OAuth 2.0 Client-Credentials Grant (see Section 4.1). The JWT payload MUST use the same set of claims as listed in Section 4.1. When using the same set of values as per Section 4.1 this leads to a request with the following form (with line breaks for clarity):


POST /lti/auth/token HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=authorization_code&code=n0esc3NRze7LTCu7iYzS6a5acc3f0ogp4&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer
&client_assertion=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9
.eyJpc3MiOiJ0b29sLmNvbSIsInN1YiI6Ind3dy5leGFtcGxlLmNvbSIsImF1ZCI6Imh0dHBzOi8vd3d3LmV4YW1wbGUuY29tL2x0aS9hdXRoL3R
va2VuIiwiaWF0IjoiMTQ4NTkwNzIwMCIsImV4cCI6IjE0ODU5MDc1MDAiLCJqdGkiOiIyOWY5MGMwNDdhNDRiMmVjZTczZDAwYTA5MzY0ZDQ5YiJ9
.liArqLDIF-xGcCu8ythy0HlzntxwZ90AYTnwH-daCQQ
&scope=http%3A%2F%2Fimsglobal.org%2Fspec%2Flti-ags%2Fscope%2Flineitem%20http%3A%2F%2Fimsglobal.org%2Fspec%2Flti-ags%2Fscope%2Fresult%2Fread        

The authorization server decodes the JWT and MUST validate the values for the iss, sub, exp, aud and jti claims, followed by verifying the signature. If it finds the request to be a valid, it generates and returns an access token, with a response of this form:


HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
    "access_token" : "dkj4985kjaIAJDJ89kl8rkn5",
    "token_type" : "bearer",
    "expires_in" : 3600,
    "scope" : "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem https://purl.imsglobal.org/spec/lti-ags/scope/result/read"    
}        

As per [RFC7519] the token MUST ONLY contain ASCII characters (0x20-0x7A) and SHOULD be at least 15 characters in length. The token MAY be a JWT (see below). 1EdTech recommends a default expiry time of 1 hour (3600 seconds). The bearer of the token can use it until the token expires (as evidenced by a failed request) but 1EdTech recommends that a Consumer manages tokens such that once they have expired (allowing for clock skew between the systems), it requests a new one when needed.

4.2.1.1 Using a JWT as an Access Token

As in the case of Client Credentials, the access token itself could be a JWT. Therefore Consumers SHOULD treat the access token returned by the authorization server as an opaque string. Any meaning that the token may have is relevant only to the authorization server and resource provider. If a resource provider does not wish to manage access tokens, it can use a JWT to encapsulate the details of the token so that the bearer provides the details with each service request for verification.

4.2.2 Token Refresh

When requesting an access token as part of the Authorization Code Grant process, an Authorization Server MAY return a 'Refresh Token'. The refresh token can be used to obtain new access tokens using the same authorization grant: this is described in Section 6 of [RFC6749]. The use of the Refresh Token avoids the choreography for obtaining the credentials to gain access to the Authorization Server.

The Consumer makes a refresh request to the token endpoint by adding the following parameters using the application/x-www-form-urlencoded format with a character encoding of UTF-8 in the HTTP request entity-body the set of parameters (Section 6 of [RFC6749]) used to request an access token are:

grant_type
REQUIRED. Value MUST be set to refresh_token.
refresh_token
REQUIRED. The refresh token issued to the Consumer.
scope
REQUIRED. The scope of the access request. The requested scope MUST NOT include any scope not originally granted by the resource owner.

An example of the request message is shown below in which two scopes (scopename1 and scopename2) are identified:


POST /token HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

grant_type=refresh_token&refresh_token=tGzv3JOkF0XG5Qx2TlKWIA&scope=scopename1%20scopename2
    		

If valid and authorized, the authorization server issues an access token as described earlier in Section 4.2 of this document. If the request failed verification or is invalid, the authorization server returns an error response as described earlier in Section 4.2 of this document.

The authorization server MAY issue a new refresh token, in which case the client MUST discard the old refresh token and replace it with the new refresh token. The authorization server MAY revoke the old refresh token after issuing a new refresh token to the client. If a new refresh token is issued, the refresh token scope MUST be identical to that of the refresh token included by the Consumer in the request.

4.2.3 Token Revocation

There may be deployments in which revocation of an access token is useful. The Token Revocation process is based upon [RFC7009]. The Consumer requests the revocation of a particular token by making an HTTP POST request (using TLS) to the token revocation endpoint URL. Note that [RFC7009] states that implementations MUST support the revocation of refresh tokens and SHOULD support the revocation of access tokens.

The client constructs the request by including the following parameters using the "application/x-www-form-urlencoded" format in the HTTP request entity-body:

token
REQUIRED. The token that the client wants to get revoked.
token_type_hint
REQUIRED. MUST be set to either access_token or refresh_token.

An example of the request message is shown below:


POST /revoke HTTP/1.1
Host: server.example.com
Authorization: Basic czZCaGRSa3F0MzpnWDFmQmF0M2JW
Content-Type: application/x-www-form-urlencoded

token=45ghiukldjahdnhzdauz&token_type_hint=refresh_token
    

The authorization server responds with HTTP status code 200 if the token has been revoked successfully or if the client submitted an invalid token.

When the request for revocation is rejected the error presentation conforms to the definition in Section 5.2 of [RFC6749]. The following additional error code is defined for the token revocation endpoint:

unsupported_token_type
The authorization server does not support the revocation of the presented token type. That is, the client tried to revoke an access token on a server not supporting this feature.

4.3 Dynamic Client Registration

When using OAuth 2, registration of the Consumer with an authorization server MUST comply with OAuth 2.0 Dynamic Client Registration Protocol [RFC7591].

4.3.1 Consumer Registration

The actual client registration starts when the Consumer posts a registration request to the authorization server (the mechanism for obtaining the specific endpoint is described in Obtaining the Registration URL). Use of an Initial Access Token with a client registration request is OPTIONAL. Use of the 'Software Statement' is NOT RECOMMENDED. Use of a Software Statement will be clarified in later versions of the Security Framework. The client registration request is sent to the client registration endpoint and the process for obtaining that URL is described in the next sub-section. The client registration request MUST be sent using HTTPS with the TLS 1.2 or 1.3 protocol.

The properties of the JSON body MUST be implemented as described in the following list. All URLs MUST use HTTPS (e.g. https://example.com/logo.png). All required properties MUST be present in the registration request in order for it to be accepted by the authorization server. Arrays MUST be used even when a single value is to be sent.

client_name
REQUIRED. The human-readable name of the Consumer.
client_uri
REQUIRED. URL string of a web page that which describes the Consumer.
tos_uri
REQUIRED. URL string that points to a human-readable Terms of Service document for the Consumer that describes a contractual relationship between the end-user and the client that the end-user accepts when authorizing the Consumer.
policy_uri
REQUIRED. URL string that points to a human-readable privacy policy document that describes how the deployment organization collects, uses, retains, and discloses personal data.
software_id
REQUIRED. A unique identifier string assigned by the Consumer developer or software publisher used by registration endpoints to identify the Consumer software to be dynamically registered. This value SHOULD remain the same for all instances of the Consumer software.
software_version
REQUIRED. A version identifier string for the Consumer software identified by software_id. The value of the software_version SHOULD change on any update to the Consumer software identified by the same software_id.
redirect_uris
REQUIRED ARRAY. The set of redirection URI strings for use in the OAuth 2.0 flow.
scope
REQUIRED. In the registration request, this is a string containing a space-separated list of scope values that this Consumer may include when requesting access tokens.
token_endpoint_auth_method
OPTIONAL. String indicator of the requested authentication method for the token endpoint. For the Security Framework, only permitted value is client_secret_basic. Therefore, the client uses the HTTP Basic as defined in OAuth 2.0 [RFC6749], Section 2.3.1. If omitted, the default is client_secret_basic.
grant_types
OPTIONAL ARRAY. Array of OAuth 2.0 grant type strings. The permitted values are:
  • client_credentials - the client credentials grant type defined in OAuth 2.0
  • authorization_code - the authorization code grant type defined in OAuth 2.0
  • refresh_token - the refresh token grant type defined in OAuth 2.0
If the token endpoint is used in the grant type, the value of this parameter MUST be the same as the value of the grant_type parameter passed to the token endpoint defined in the grant type definition. If omitted, the default behavior is that the client will use only the authorization_code Grant Type.
response_types
OPTIONAL ARRAY. Array of the OAuth 2.0 response type strings that the Consumer can use at the authorization endpoint. The ONLY permitted value is code which denotes the authorization code response type defined in OAuth 2.0.
logo_uri
OPTIONAL. URL string that references a logo for the Consumer. If present, the server SHOULD display this image to the end-user during approval. The value of this field MUST point to a valid image file.
contacts
OPTIONAL ARRAY. Array of strings representing ways to contact people responsible for this Consumer, typically email addresses. The authorization server MAY make these contact addresses available to end-users for support requests for the Consumer. Privacy constraints MUST be supported as applicable
jwks_uri
OPTIONAL. URL string referencing the JSON Web Key (JWK) Set [RFC7517] document for the Consumer, which contains the client’s public keys. The value of this field MUST point to a valid JWK Set document. Use of this parameter is preferred over the jwks parameter, as it allows for easier key rotation. The jwks_uri and jwks parameters MUST NOT both be present in the same request or response.
jwks
OPTIONAL. Consumer JSON Web Key Set [RFC7517] document value, which contains the consumer’s public keys. The value of this field MUST be a JSON object containing a valid JWK Set. These keys can be used by higher-level protocols that use signing or encryption. This parameter is intended to be used by clients that cannot use the jwks_uri parameter, such as native clients that cannot host public URLs. The jwks_uri and jwks parameters MUST NOT both be present in the same request or response.

An example Client Registration request message is shown below.


POST https://clrauth.azurewebsites.net/connect/register HTTP/1.1
Accept: application/json
Content-Type: application/json; charset=utf-8

{
    "client_name": "Example Consumer",
    "client_uri": "https://consumer.example.com/",
    "logo_uri": "https://consumer.example.com/logo.png",
    "tos_uri": "https://consumer.example.com/terms",
    "policy_uri": "https://consumer.example.com/privacy",
    "software_id": "c88b6ed8-269e-448e-99be-7e2ff47167d1",
    "software_version": "v4.0.30319",
    "redirect_uris": [
        "https://consumer.example.com/Authorize"
    ],
    "token_endpoint_auth_method": "client_secret_basic",
    "grant_types": [
        "authorization_code",
        "refresh_token"
    ],
    "response_types": [
        "code"
    ],
    "scope": "https://purl.imsglobal.org/spec/clr/v1p0/scope/delete https://purl.imsglobal.org/spec/clr/v1p0/scope/readonly https://purl.imsglobal.org/spec/clr/v1p0/scope/replace"
}
					

Several of the properties above require the provision of URIs. Use of these could be abused for server-side request forgery. Therefore the Security Considerations, Section 5 of [RFC7591], SHOULD be followed.

If the authorization server accepts the registration request, it will store the information provided in the request and respond HTTP 201 Created with a registration response that includes 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 authorization server deems necessary. The Client Registration response body, for a successful request, MUST also contain the following information:

client_id
REQUIRED. OAuth 2.0 client identifier string. It SHOULD NOT be currently valid for any other registered Consumer.
client_secret
REQUIRED. OAuth 2.0 client secret string. This MUST be unique for each client_id and SHOULD be unique for multiple instances of a client using the same client_id. This value is used by confidential clients to authenticate to the token endpoint, as described in OAuth 2.0 [RFC6749], Section 2.3.1..
client_id_issued_at
REQUIRED. Time at which the client identifier 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
REQUIRED. Time at which the client secret will expire or 0 if it will not expire. 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.

An example Client Registration response message for a successful request is shown below.


HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
	"client_id": "4ad36680810420ed",
	"client_secret": "af7aa0d679778e12",
	"client_id_issued_at": 1565715850,
	"client_secret_expires_at": 1597338250,
	"client_name": "Example Consumer",
	"client_uri": "https://consumer.example.com/",
	"logo_uri": "https://consumer.example.com/logo.png",
	"tos_uri": "https://consumer.example.com/terms",
	"policy_uri": "https://consumer.example.com/privacy",
	"software_id": "c88b6ed8-269e-448e-99be-7e2ff47167d1",
	"software_version": "v4.0.30319",
	"redirect_uris": [
		"https://consumer.example.com/Authorize"
	],
	"token_endpoint_auth_method": "client_secret_basic",
	"grant_types": [
		"authorization_code",
		"refresh_token"
	],
	"response_types": [
		"code"
	],
	"scope": "https://purl.imsglobal.org/spec/clr/v1p0/scope/readonly"
}
					

When a registration error condition occurs, the authorization server returns an HTTP 400 status code (unless otherwise specified) with content type "application/json" consisting of a JSON object describing the error in the response body. The properties used are:

error
REQUIRED. Single ASCII error code string. The permitted value space is:
  • invalid_redirect_uri - the value of one or more redirection URIs is invalid.
  • invalid_client_metadata - the value of one of the Consumer metadata fields is invalid and the server has rejected this request. Note that an authorization server MAY choose to substitute a valid value for any requested parameter of a Consumer’s metadata.
  • invalid_software_statement - the software statement presented is invalid. This MUST only be returned if a Software Statement has been supplied in the registration request. Use of a Software Statement is NOT RECOMMENDED.
  • unapproved_software_statement - the software statement presented is not approved for use by this authorization server. This MUST only be returned if a Software Statement has been supplied in the registration request. Use of a Software Statement is NOT RECOMMENDED.
error_description
OPTIONAL. Human-readable ASCII text description of the error used for debugging.
4.3.1.1 Use of an Initial Access Token

An Initial Access Token is an OAuth 2.0 access token optionally issued by an authorization server to a developer or Consumer and used to authorize calls to the client registration endpoint. Use of an Initial Access Token is OPTIONAL. If an 1EdTech specification is to include the use of an Initial Access Token the following MUST occur:

  • The 1EdTech specification MUST define if the use of the Initial Access Token is REQUIRED or OPTIONAL. Usage MUST NOT be RECOMMENDED.
  • The 1EdTech specification MUST justify the usage of an Initial Access Token and this justification MUST be supported by the 1EdTech Security Committee. It is RECOMMENDED that an 1EdTech Project Group obtain the 1EdTech Security Committee's support for the use of an Initial Access Token before including its use in the specification.
  • Usage of an Initial Access Token MUST follow [RFC7591] Section 3. [RFC7591] does not define how the Initial Access Token is to be obtained. Therefore, the following is RECOMMENDED:
    • Obtaining the token SHOULD use one of the approaches defined in Section 4 of the 1EdTech Security Framework
    • The token SHOULD be obtained from the same endpoint as per the OAuth 2.0 approach being used in the specification
    • An appropriate scope MUST be defined and this scope MUST NOT be used to define any other access constraint. The scope MUST end with the sub string '/scope/initialaccesstoken'
  • The process for obtaining the Initial Access Token MUST be defined in the 1EdTech specification.
4.3.1.2 Use of a Software Statement

A software statement is a JSON Web Token (JWT) [RFC7519] that asserts metadata values about the client software as a bundle. A set of claims that can be used in a software statement are defined in [RFC7591] Section 2. There is little practical experience in the use of Software Statements. Therefore, the use of Software Statements is NOT RECOMMENDED. Later versions of the 1EdTech Security Framework will review the use of Software Statements.

An 1EdTech specification that includes the use of the Software Statement MUST follow [RFC7591] and MUST provide a strong justification for such use. The 1EdTech Security Committee MUST review and support such a justification. It is RECOMMENDED that an 1EdTech Project Group obtain the 1EdTech Security Committee's support for the use of a Software Statement before including its use in the specification.

4.3.2 Obtaining the Registration URL

To start the registration process, the Consumer must obtain the Provider's domain authority. When presented with an unknown Provider the Consumer MUST request the Provider's Service Description Document (SDD). The endpoint for reading the SDD is '.../discovery'. Rate-limited access to this endpoint is RECOMMENDED. An example request for an SDD takes the form of (this example is for an 1EdTech Comprehensive Learner Record based-service):


GET /ims/clr/v1p0/discovery HTTP/1.1
Host: provider.example.com
Accept: application/json     
    				

Access to the discovery endpoint MUST NOT be protected. The SDD MUST be provided over HTTPS with TLS 1.2 or 1.3.

The response to this request is the SDD supplied as a JSON encoded payload. The structure and format of this payload MUST follow that of the OpenAPI 3.0 Specification [OAS3P0]. The SDD being supplied MUST be a profiled version of the OpenAPI 3.0 (JSON) file provided as one of the artifacts released as part of the definition of an 1EdTech service specification. This profiled version contains all of the details about the supported set of service end-points, the supported optional data fields, definitions of the proprietary data fields supplied using the permitted extension mechanisms, definitions of the available proprietary endpoints, and information about the security mechanisms.

The URL for the Client Registration MUST be contained in the property named x-imssf-registrationUrl. This is an 1EdTech controlled extension to the OpenAPI specification. This new property is inserted into the securitySchemes within the components section of the OpenAPI file structure. An example of the partial OpenAPI file is shown below.


...
"components" : {
    "securitySchemes" : {
        "OAuth2CCG" : {
            "type" : "oauth2",
            "description" : "OAuth 2.0 Client Credentials authorization",
            "x-imssf-registrationUrl" : "provider.example.com/registration",
            "flows" : {
                "clientCredentials" : {
                    "tokenUrl" : "provider.example.com/token",
                    "scopes" : {
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/delete" : "...",
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/readonly" : "...",
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/replace" : "..."
                    }
                }
            }
        },
        "OAuth2ACG" : {
            "type" : "oauth2",
            "description" : "OAuth 2.0 Authorization Code Grant authorization",
            "x-imssf-registrationUrl" : "provider.example.com/registration",
            "flows" : {
                "authorizationCode" : {
                    "tokenUrl" : "provider.example.com/token",
                    "authorizationUrl" : "provider.example.com/authorize",
                    "refreshUrl" : "provider.example.com/token",
                    "scopes" : {
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/delete" : "...",
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/readonly" : "...",
                        "https://purl.imsglobal.org/spec/clr/v1p0/scope/replace" : "..."
                    }
                }
            }
        }
    },
    "schemas" : {
                 ...
    }
}
...
					

A more detailed example is given in the Appendices.

An implementation MAY also provide the OpenAPI 3.0 (YAML) file. YAML files permit human-readable annotations of the contents - this is not possible with the JSON equivalent. Access to the YAML-based version of the OpenAPI file is outside the scope of this framework.

Upon receiving a SDD 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 SDD data, if valid, up to the expiration indicated, either at the time indicated by the Expires header or max-age seconds from request time.

4.3.3 Consumer Registration Management

There will be some scenarios in which the Consumer registration information may need to be read, and/or changed and/or deleted. Management of client registration information is covered in [RFC7592]: 'OAuth 2.0 Dynamic Client Registration Management Protocol'. Support for Client Registration Management is OPTIONAL. If a binding of an 1EdTech service specification wishes to make Client Registration Management available, the following MUST be completed:

  • The functionality MUST comply with the [RFC7952] and the subset of features to be used MUST be clearly identified. For example only some of read, update and delete capabilities may be available
  • The conformance requirements, in the corresponding Conformance & Certification document, MUST state whether support for Client Registration Management is OPTIONAL or REQUIRED. Support of the features available in [RFC7952] MUST be identified as either OPTIONAL or REQUIRED
  • Access to the Client Registration Management endpoints MUST be secured as per [RFC6750] (the appropriate registration access token MUST be supplied in the response to the Consumer Registration request). The security considerations addressed in Section 5 [RFC7592], 'Security Considerations', MUST be followed
  • The client registration management information exchange MUST be secured at the transport-layer using either TLS 1.2 or TLS 1.3.

5. Message Security and Message Signing

When transferring a User Agent from one entity to another the redirecting party SHOULD sign the Message effecting this transfer using a JWT. Messages are JWTs sent through the browser by auto-POSTing from sender to some endpoint URL on the message receiver. The signature on the JWT is always signed by the private key of the message sender. Therefore, for platform-to-tool messages, the platform signs the JWT with their private key, and the client then verifies the signature on the message payload they receive by using the platform's public key they obtained out-of-band. In an example out-of-band registration work flow, the public-key/key-set-URL exchange can happen during Tool registration: the Platform registers the Consumer, gives the Consumer its public-key/key-set-URL; the Consumer reciprocates.

A Message MAY carry additional Claims related to the user interface flow presented to the end user: these Claims MUST be defined in the corresponding specification (for example, the LTI Specification [LTI-13], which defines the concepts of LTI-compliant platforms and tools).

5.1 Platform-Originating Messages

When a Platform acts as an Identity Provider (IDP), it MUST pass identity information with each Message. To do so, it MUST use a subset of Section 2 of OpenID Connect Core [OPENID-CCORE] (see Section 5.1.1 of that document for more details) to provide user Authentication to the Tool (see Figure 6 for a schematic representation of this architecture). This is done using a combination of the 'Initiating Login from a Third Party' and 'Implicit Flow' of the OpenID Connect Core [OPENID-CCORE] (Sections 4 and 3.2.1 respectively). The authentication relies upon the Platform and Tool being aware of various identifiers for each other as well as using public key encryption for signing the messages.

Figure 6 Information flow for platform-originating messages.

The key points in the figure above are:

  • The Tool must have been allocated an OAuth 2 client_id (usually by an Authorization Server and this may be owned by the Platform);

  • The Platform must be given the client_id for the Tool (using some out-of-band registration process if not assigned by the Platform);

  • The Tool must be given the Public Key and Issuer Identifier (issuer_id) for the Platform (using some out-of-band registration process). See 6. Key Management for more details on Key Management;

  • The Platform must have the Private Key pair to its announced Public Key and a set of Subject identifiers (subject_id) for the set of users that will be given access to the Tool.

5.1.1 OpenID Connect Launch Flow Overview

The Implicit Flow exchange consists of the 6 steps as defined in Section 3.2.1 of OpenID Connect Core [OPENID-CCORE]. However, in order to stop the work flow being vulnerable to the 'Login Cross-Site Request Forgery (CSRF)' each message request MUST be treated as a 3rd party initiated login, as defined in OpenID Connect: Initiating Login from a Third Party, which triggers an OpenID Connect Implicit flow between the tool, acting as the Relying Party, and the platform, acting as the Identity Provider.

In 3rd party initiated login, the login flow is initiated by an OpenID Provider or another party, rather than the Relying Party. In this case, the initiator redirects to the Relying Party at its login initiation endpoint, which requests that the Relying Party send an Authentication Request to a specified OpenID Provider. This login initiation endpoint can be a deep link at the Relying Party, rather than a default landing page.

The OpenID Connect launch flow is shown in Figure 7.

Figure 7 The OpenID Connect launch flow.

As part of the out-of-band registration process the following information must also be distributed:

  • The Tool must provide the single URL that the Platform will use to initiate the OpenID Connect authorization flow (called the '3rd Party initiated login end-point');

  • The Tool must provide one or multiple redirect URIs that are valid end points where the authorization response can be sent. The number of distinct redirect URIs to be supported by a platform is not specified;

  • The Platform must provide the single end-point to which the browser will be redirected, by the Tool, to initiate the OpenID Connect authentication flow (called the OIDC Authorization end-point').

5.1.1.1 Step 1: Third-party Initiated Login

When a user wants to launch into a Tool, the Platform will start the OpenID Connect flow by redirecting the User Agent (UA) to the 3rd party initiated login end point. The redirect may be a form POST or a GET - a Tool must support either case, with the following parameters.

iss
REQUIRED. The issuer identifier identifying the learning platform.
login_hint
REQUIRED. Hint to the Authorization Server about the login identifier the End-User might use to log in. The permitted values will be defined in the host specification.
target_link_uri
REQUIRED. The actual end-point that should be executed at the end of the OpenID Connect authentication flow.

NOTE: Other parameters MAY be supplied to provide important context for a specific message exchange i.e. as defined in the corresponding 1EdTech specification.

5.1.1.2 Step 2: Authentication Request

The tool must then perform an authentication request as defined in Section 3.1.2.1 of the [OPENID-CCORE]. The tool sets the CSRF token and binds it to a state parameter, and redirects the UA to the platform at the OIDC Authentication endpoint registered with the iss with the following parameters:

scope
REQUIRED as per [OPENID-CCORE]. OpenID Connect requests MUST contain the openid scope value. Other scope values MAY be present.
response_type: id_token
REQUIRED as per [OPENID-CCORE]. Determines the authorization processing flow to be used, including what parameters are returned from the endpoints used.
client_id
REQUIRED as per [OPENID-CCORE]. The Tool’s Client ID for this issuer.
redirect_uri
REQUIRED as per [OPENID-CCORE]. One of the registered redirect URIs.
login_hint
REQUIRED. As passed in the initiate login request.
state
RECOMMENDED as per [OPENID-CCORE]. Opaque value for the platform to maintain state between the request and callback and provide Cross-Site Request Forgery (CSRF) mitigation. This is REQUIRED if the state parameter is present in the Authorization Request.
response_mode: form_post
REQUIRED. The Token can be lengthy and thus should be passed over as a form POST.
nonce
REQUIRED. String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token.
prompt: none
REQUIRED. Since the message launch is meant to be sent from a platform where the user is already logged in. If the user has no session, a platform must just fail the flow rather than ask the user to log in.
5.1.1.3 Step 3: Authentication Response

Once the platform has validated the redirect_uri as a valid end point for the client_id, and the current logged in user matches the login_hint, the platform can construct the id_token.

The id_token needs to contain, in addition to the user’s identity claims, the message claims required for the tool to fulfill the launch request.

The authentication response is sent to the redirect_uri with the following parameters:

state
REQUIRED - see Section 3.2.2.5 of the [OPENID-CCORE].
id_token
REQUIRED - see Section 3.2.2.5 of the [OPENID-CCORE]. This also contains the other message specific claims and the nonce passed in the auth request.
5.1.1.4 Step 4: Resource is displayed

The tool, after decoding and validating the id_token and verified the state matches the current state attached to the browser session, will display the resource, by, for example, issuing a redirect to the target_link_uri as received in the first step of that flow, concluding the Message request.

5.1.1.5 Authentication Error Response

As per Section 3.1.2.6 of the OpenID Connect specification [OPENID-CCORE].

5.1.2 ID Token

In order to enable the authentication of end users, OpenID Connect extends OAuth 2.0 with the ID Token data structure. The ID Token is a security token that contains Claims about the Authentication of an end user made by an authorization server when using a Tool, and potentially other requested Claims. The ID Token is represented as a JWT [RFC7519] and the JWS is produced using the Platform's Private Key. See Section 2 of [OPENID-CCORE] for more information regarding the ID Token.

The ID Token uses these Claims:

iss
REQUIRED. Issuer Identifier for the Issuer of the message i.e. the Platform. The iss value is a case-sensitive URL using the HTTPS scheme that contains: scheme, host; and, optionally, port number, and path components; and, no query or fragment components.
aud
REQUIRED. Audience(s) for whom this ID Token is intended i.e. the Tool. It MUST contain the OAuth 2.0 client_id of the Tool as an audience value. It MAY also contain identifiers for other audiences. In the general case, the aud value is an array of case-sensitive strings. In the common special case when there is one audience, the aud value MAY be a single case-sensitive string. It is RECOMMENDED that an array is used even when only a single value is to be sent.
sub
REQUIRED. Subject Identifier. A locally unique and never reassigned identifier within the Issuer for the end user, which is intended to be consumed by the Tool, (for example, it might be something like 24400320 or AItOawmwtWwcT0k51BayewNvutrJUqsvl6qs7A4). It MUST NOT exceed 255 ASCII characters in length. The sub value is a case-sensitive string. This MUST be the same value as the Platform's User ID for the end user.
exp
REQUIRED. Expiration time on or after which the Tool MUST NOT accept the ID Token for processing. When processing this parameter, the Tool MUST verify that the time expressed in this Claim occurs after the current date/time. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew. This Claim's value MUST be a JSON number representing the number of seconds offset from 1970-01-01T00:00:00Z (UTC). See [RFC3339] for details regarding date/times in general and UTC in particular.
iat
REQUIRED. Time at which the Issuer generated the JWT. Its value is a JSON number representing the number of seconds offset from 1970-01-01T00:00:00Z (UTC) until the generation time.
nonce
REQUIRED. String value used to associate a Tool session with an ID Token, and to mitigate replay attacks. The nonce value is a case-sensitive string.
azp
OPTIONAL. Authorized party - the party to which the ID Token was issued. If present, it MUST contain the OAuth 2.0 Tool ID of this party. This Claim is only needed when the Token has a single audience value and that audience is different than the authorized party. It MAY be included even when the authorized party is the same as the sole audience. The azp value is a case-sensitive string containing a String or URI value.

The Claims in an ID Token JWT might look like this (non-normative) example:


{
    "iss": "https://lms.uofexample.edu",             // Platform Issuer Identifier
    "sub": "24400320",                               // Subject Identifier of the User
    "aud": "s6BhdRkqt3",                             // Client Identifier for the Client
    "nonce": "n-0S6_WzA2Mj",
    "exp": 1311281970,
    "iat": 1311280970
}          
        

The User information passed upon launch depends upon relevant privacy settings the Platform must apply. At a minimum, the Platform must present a permanent identifier for the user in the sub Claim.

5.1.3 Authentication Response Validation

Tools MUST validate the ID Token in the token response in the following manner:

  1. The Tool MUST Validate the signature of the ID Token according to JSON Web Signature [RFC7515], Section 5.2 using the Public Key from the Platform;

  2. The Issuer Identifier for the Platform MUST exactly match the value of the iss (Issuer) Claim (therefore the Tool MUST previously have been made aware of this identifier);

  3. The Tool MUST validate that the aud (audience) Claim contains its client_id value registered as an audience with the Issuer identified by the iss (Issuer) Claim. The aud (audience) Claim MAY contain an array with more than one element. The Tool MUST reject the ID Token if it does not list the client_id as a valid audience, or if it contains additional audiences not trusted by the Tool. The request message will be rejected with a HTTP code of 401;

  4. If the ID Token contains multiple audiences, the Tool SHOULD verify that an azp Claim is present;

  5. If an azp (authorized party) Claim is present, the Tool SHOULD verify that its client_id is the Claim's value;

  6. The alg value SHOULD be the default of RS256 or the algorithm sent by the Tool in the id_token_signed_response_alg parameter during its registration. The approved list of algorithms that MUST be used is given in the Best Practices;

  7. The current time MUST be before the time represented by the exp Claim;

  8. The Tool MAY use the iat Claim to reject tokens that were issued too far away from the current time, limiting the amount of time that it needs to store nonces used to prevent attacks. The Tool MAY define its own acceptable time range;

  9. The ID Token MUST contain a nonce Claim. The Tool SHOULD verify that it has not yet received this nonce value (within a Tool-defined time window), in order to help prevent replay attacks. The Tool MAY define its own precise method for detecting replay attacks.

5.2 Tool-Originating Messages

When a Message does not assert the user identity, the sender signs and secures the JWT using the JSON Web Signature (JWS) defined in [RFC7515]. The Tool typically sends such messages to the Platform. Figure 8 is a schematic representation of this architecture.

Figure 8 Information flow for tool-originating messages.

The key points in Figure 8 are:

  • The Tool must have been allocated an OAuth 2 client_id (usually by an Authorization Server and this may be owned by the Platform)

  • The Platform must be given the Public Key and client_id for the Tool (using some out-of-band registration process if not assigned by the Platform). See 6. Key Management for more details on Key Management.

  • The Tool must be given the Issuer Identifier (issuer_id) for the Platform (using some out-of-band registration process)

  • The Tool must have the Private Key pair to its announced Public Key.

5.2.1 Form Parameter

The sender sends the JWT via a form HTTP POST with a single parameter:

JWT (REQUIRED). JWS-signed token containing the Message Claims. The JWS is produced using the Tool's Private Key.

5.2.2 Tool JWT

The Tool JWT is a security token which contains Claims about the Authentication of an end user made by an authorization server when using a Tool, and potentially other requested Claims. The Tool JWT is represented as a JWT [RFC7519].

The Tool JWT uses these claims:

iss
REQUIRED. Issuer Identifier for the Issuer of the message i.e. the Tool. It must be the OAuth 2.0 client_id of the Tool (this MAY be provided to it by the Platform upon registration of the Tool).
aud
REQUIRED. Audience(s) for whom this Tool JWT is intended. It MUST contain the case-sensitive URL used by the Platform to identify itself as an Issuer in platform-originating Messages. In the common special case when there is one audience, the aud value MAY be a single case-sensitive string. It is RECOMMENDED that an array is used even when only a single value is to be sent.
exp
REQUIRED. Expiration time on or after which the Platform MUST NOT accept the Tool JWT for processing. When processing this parameter, the Platform MUST verify that the time expressed in this Claim occurs after the current date/time. Implementers MAY provide for some small leeway, usually no more than a few minutes, to account for clock skew (see the Best Practice Recommendations on compensating for clock skew). This Claim's value MUST be a JSON number representing the number of seconds offset from 1970-01-01T00:00:00Z (UTC). See [RFC3339] for details regarding date/times in general and UTC in particular.
iat
REQUIRED. Time at which the Issuer generated the Tool JWT. Its value is a JSON number representing the number of seconds offset from 1970-01-01T00:00:00Z (UTC) until the generation time.
nonce
REQUIRED. String value used to associate a Tool session with a Tool JWT, and to mitigate replay attacks. The nonce value is a case-sensitive string.
azp
OPTIONAL. Authorized party - the party to which the Tool JWT was issued. If present, it MUST contain the same value as in the aud Claim. The azp value is a case-sensitive string containing a String or URI value.

The Claims in a Tool JWT might look like this (non-normative) example:


{
    "iss": "s6BhdRkqt3",                               // Client Identifier of the Client
    "aud": "https://lms.uofexample.edu",               // Platform Issuer Identifier
    "nonce": "n-0S6_WzA2Mj",
    "exp": 1311281970,
    "iat": 1311280970
}          

5.2.3 Authentication Response Validation

Platforms MUST Validate the Message Tool JWT in the Token Response in the following manner:

  1. The Platform MUST validate the signature of the Tool JWT according to JSON Web Signature [RFC7518] using the algorithm the Tool specifies in the alg header parameter of the JOSE Header. The Platform must use the Public Key from the Tool to validate the message;

  2. The client_id for the Tool MUST exactly match the value of the iss (Issuer) Claim;

  3. The Platform MUST validate that the aud (audience) Claim contains its advertised Issuer URL. The Platform must reject the Tool JWT if it does not list the Platform as a valid audience, or if it contains additional audiences not trusted by the Platform;

  4. If the Token contains multiple audiences, the Platform SHOULD verify that an azp Claim is present;

  5. If an azp (authorized party) Claim is present, the Platform SHOULD verify that its Issuer URL is the Claim Value.

  6. The alg value SHOULD be the default of RS256 or the algorithm specified by the Platform to the Tool during registration. The approved list of algorithms that MUST be used is given in the Best Practices;

  7. The current time MUST be before the time represented by the exp Claim;

  8. The Platform MAY use the iat to reject tokens that were issued to far away from the current time, limiting the amount of time that it needs to store nonces used to prevent attacks. The Platform MAY define its own acceptable time range;

  9. The Tool JWT MUST contain a nonce Claim. The Platform SHOULD verify that it has not yet received this nonce value (within a Platform-defined time window), in order to prevent replay attacks. The Platform MAY define its own precise method for detecting replay attacks.

5.3 Message Specific Claims

Message Tool JWTs MAY contain other Claims. The receiver of a Message Tool JWT MUST ignore any claims it does not understand. Vendors MAY extend the Message Tool JWT by adding additional Claims using a "Public Claim Name" as defined in Section 4.2 of the JWT in the [RFC7519] specification. Vendors SHOULD only use domains that they own, and they MUST prefix these domains with "http://".

5.4 Message Signing

Message Tool JWTs MUST be signed using the method described in [RFC7518], Message Tool JWTs MUST NOT use none as the alg value.

Message Client JWTs SHOULD NOT use the JWS x5u, x5c, jku, or jwk Header Parameter fields. Instead, Platforms and Tools should communicate the keys to use for Message JWS Tokens during registration.

5.5 Dynamic Client Registration

When using OpenID Connect, registration of the Tool with a Platform MUST comply with [OPENID-DCR] and [OPENID-DIS].

5.5.1 Dynamic Registration Protocol Overview

This registration protocol uses the OIDC Discovery [OPENID-DIS] and OIDC Dynamic Client Registration [OPENID-DCR] specifications. In the context of this specification, the Tool plays the role of the Consumer (or Client or Relying Party), and the Platform the one of the OpenID Provider. Therefore, the registration is done in four phases:

  1. The Platform initiates the registration by using the initiate registration endpoint supplied by the Tool. This is mediated by the browser, typically by opening an IFrame to the initiate registration end-point. The tool may include a User Interface (UI) to complete the registration on the tool side;
  2. The tool discovers the platform's OpenID configuration using the provided openid-configuration endpoint, as defined in OIDC Discovery [OPENID-DIS] specification;
  3. The tool uses the registration endpoint present in the OpenID configuration to request a registration as per OIDC Dynamic Client Registration [OPENID-DCR] specification. The platform must immediately grant or deny the registration. A successful registration means the tool is properly configured, but it is not activated yet;
  4. The platform administrator may then review, alter, reject or activate the newly added registration.

The choreography for the OpenID Connect-based dynamic client registration process is shown in Figure 9.

Figure 9 The choreography for the OpenID Connect-based dynamic client registration process.

While the openid-configuration exposes the platform's offered capabilities to the tool, and the tool's registration includes the scopes and claims it requests access for, this process is not aimed at negotiating a contract. A Platform should accept a registration and actually allow only a subset of the required capabilities, reflected in the returned tool's registration. Furthermore, a platform admin may always either restrict or extend the offered capabilities (claims, scopes, variables) to a given tool. As usual, a Tool should not make assumptions about what is available and handle gracefully the cases were some capabilities such as claims and/or services are not exposed.

5.5.2 Registration Initiation Request (Step 1)

The registration initiation launch allows the registration flow to be triggered from the platform UI, typically by opening an IFrame or a new Tab to that endpoint. How the initiate registration request endpoint is shared is not specified and happens out-of-band. It may be the same registration endpoint for all registration requests or specific for a given registration request. For example the tool may generate a specific registration URL for each institution and communicate it to the platform administrator to trigger the registration.

The initiation launch is a User Agent redirect to the initiation registration URL and appends the following query parameters to the URL:

openid_configuration
REQUIRED. The endpoint to the open id configuration to be used for this registration, encoded as per [RFC3986] Section 3.4.
registration_token
OPTIONAL. the registration access token. If present, it must be used as the access token by the tool when making the registration request to the registration endpoint exposed in the OpenID configuration.

The registration token MUST be:

  • Short lived - typically 1 hour to allow enough time for some UI interaction on the tool side happening before the actual registration request is made
  • Usable only once - the token must not allow more than one registration.

5.5.3 Discovery and OpenID Configuration (Step 2)

This section follows the OIDCDiscovery specification [OPENID-DIS] but relaxes the requirement on the OpenID Configuration Endpoint's URL since the URL is actually passed during the initiate registration request, allowing the platform to possibly tailor a configuration for a given registration.

The Platform must make to the OpenID Configuration URL's endpoint as a path concatenated with the Issuer. If applicable, the appended path should be the OIDCDiscovery defined /.well-known/openid-configuration. The URL may also contain query parameters. The URL must not contain any fragment parameter. For example, considering the OpenID Configuration declares the issuer as https://platform.example.com, the following URLs would be valid OpenID Configuration endpoints:

  • https://platform.example.com/.well-known/openid-configuration
  • https://platform.example.com/.well-known/openid-configuration?r=7462647772
  • https://platform.example.com/.well-known/lti-openid-configuration
  • https://platform.example.com/lti/openid-configuration
  • https://platform.example.com/lti/openid-configuration/reg/849021

The following URLs are not valid and a Tool must abort the registration:

  • https://attacker.io/.well-known/openid-configuration
  • https://platform.example.org/.well-known/openid-configuration
  • https://lti.platform.example.com/openid-configuration
  • https://example.com/.well-known/openid-configuration

The Tool receives the OpenID configuration endpoint as a query parameter in the initiate registration request. The tool must not make any assumption about the OpenID configuration endpoint time-to-live, nor should it assume that the endpoint is meant to be shared and/or reused for other registration requests. For example, a platform may issue a short lived endpoint to a specific tool administrator so that registration can be initiated; the registration endpoint present in the OpenID configuration would then be a single usage endpoint, only allowing a single tool to be registered. Registering another tool would require the platform to deliver another openid-configuration endpoint to the tool's administrator.

An OpenID Provider Configuration Document MUST be queried using an HTTP GET request at the previously specified path. The response is a set of Claims about the OpenID Provider's configuration, including all necessary endpoints and public key location information. A successful response MUST use the 200 OK HTTP status code and return a JSON object using the application/json content type that contains a set of Claims as its members that are a subset of the metadata values defined below. Other Claims MAY also be returned.

The properties to be used for the Platform configuration payload are based upon the definitions in Section 3 of the OpenID Connect Discovery 1.0 specification [OPENID-DIS]. The properties of the JSON body MUST be implemented as described in the following list. All URLs MUST use HTTPS (e.g. https://example.com/logo.png). All required properties MUST be present in the configuration request in order for it to be accepted by the tool. Arrays MUST be used even when a single value is to be sent. Claims with zero elements MUST be omitted from the response.

issuer
REQUIRED. Platform's issuer value. A URL using the https scheme with no query or fragment component that the OpenID Provider asserts as its Issuer Identifier.
authorization_endpoint
REQUIRED. URL of the OAuth 2.0 Authorization Endpoint as per [OPENID-CCORE].
token_endpoint
REQUIRED. URL of the endpoint for the tool to request a token to access services.
jwks_uri
REQUIRED. URL of the Platform JWK Set endpoint. This may be specific per registration if the platform's issued a dedicated discovery end-point for that registration.
registration_endpoint
REQUIRED. URL of the registration endpoint. It MAY be a one time use only end-point and/or protected by access token. See [OPENID-DIS].
scopes_supported
REQUIRED ARRAY. MUST contain openid and the scopes of the supported services.
response_types_supported
REQUIRED ARRAY. MUST contain id_token and MAY offer additional values.
subject_types_supported
REQUIRED ARRAY. An array of supported Subject Identifiers as defined OpenID Core 1.0 specifications. Valid types are public (indicates the same sub is passed across tools for a given end-user) and pairwise (indicates a different sub value will be passed to different tools for the same end-user).
id_token_signing_alg_values_supported
REQUIRED ARRAY. MUST contain RS256 and MAY offer additional values. The approved list of algorithms that MUST be used is given in the Best Practices.
token_endpoint_auth_methods_supported
REQUIRED ARRAY. MUST contain private_key_jwt and MAY offer additional values.
token_endpoint_auth_signing_alg_values_supported
REQUIRED ARRAY. MUST contain RS256 and MAY offer additional values. The approved list of algorithms that MUST be used as the value of alg is given in the Best Practices.
claims_supported
REQUIRED ARRAY. OpenID claims supported by this Platform.
authorization_server
OPTIONAL. The authorization server identifier to be used as the aud when requesting an access token. If not specified, the tool must use the token_endpoint as the aud value when requesting an access token.
userinfo_endpoint
OPTIONAL. URL of the Platform's UserInfo Endpoint [OPENID-CCORE]. This URL MUST use the https scheme and MAY contain port, path, and query parameter components.
response_modes_supported
OPTIONAL ARRAY. response_mode values that this Platform supports, as specified in OAuth 2.0 Multiple Response Type Encoding Practices [OAUTH2-RESP]. If omitted, the default for Dynamic OpenID Providers is [query, fragment].
grant_types_supported
OPTIONAL ARRAY. Contains a list of the OAuth 2.0 Grant Type values that this Platform supports. Dynamic OpenID Providers MUST support the authorization_code and implicit Grant Type values and MAY support other Grant Types. If omitted, the default value is [authorization_code, implicit]. Use of the implicit grant MUST only be used in the context of OpenID Connect.
acr_values_supported
OPTIONAL ARRAY. Contains a list of the Authentication Context Class References that this Platform supports.
id_token_encryption_alg_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (alg values) supported by the Platform for the ID Token to encode the Claims in a JWT [RFC7519]
id_token_encryption_enc_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (enc values) supported by the Platform for the ID Token to encode the Claims in a JWT [RFC7519].
userinfo_signing_alg_values_supported
OPTIONAL ARRAY. Contains a list of the JWS signing algorithms (alg values) [RFC7518] supported by the UserInfo Endpoint to encode the Claims in a JWT [RFC7519]. The value none MAY be included.
userinfo_encryption_alg_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (alg values) [RFC7518] supported by the UserInfo Endpoint to encode the Claims in a JWT [RFC7519].
userinfo_encryption_enc_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (enc values) [RFC7518] supported by the UserInfo Endpoint to encode the Claims in a JWT [RFC7519].
request_object_signing_alg_values_supported
OPTIONAL ARRAY. Contains a list of the JWS signing algorithms (alg values) supported by the Platform for Request Objects, which are described in Section 6.1 of OpenID Connect Core 1.0 [OPENID-CCORE]. These algorithms are used both when the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter). Servers MUST support none and RS256. The approved list of algorithms that MUST be used is given in the Best Practices.
request_object_encryption_alg_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (alg values) supported by the Platform for Request Objects. These algorithms are used both when the Request Object is passed by value and when it is passed by reference.
request_object_encryption_enc_values_supported
OPTIONAL ARRAY. Contains a list of the JWE encryption algorithms (enc values) supported by the Platform for Request Objects. These algorithms are used both when the Request Object is passed by value and when it is passed by reference.
display_values_supported
OPTIONAL ARRAY. Contains a list of the display parameter values that the OpenID Provider supports. These values are described in Section 3.1.2.1 of OpenID Connect Core 1.0 [OPENID-CCORE].
claim_types_supported
OPTIONAL ARRAY. Contains a list of the Claim Types that the OpenID Provider supports. These Claim Types are described in Section 5.6 of OpenID Connect Core 1.0 [OPENID-CCORE]. Values defined by this specification are normal, aggregated, and distributed. If omitted, the implementation supports only normal Claims.
service_documentation
OPTIONAL. URL of a page containing human-readable information that developers might want or need to know when using the Platform. In particular, if the OpenID Provider does not support Dynamic Client Registration, then information on how to register Clients needs to be provided in this documentation.
claims_locales_supported
OPTIONAL ARRAY. Languages and scripts supported for values in Claims being returned, represented as a JSON array of BCP47 [RFC5646] language tag values. Not all languages and scripts are necessarily supported for all Claim values.
ui_locales_supported
OPTIONAL ARRAY. Languages and scripts supported for the user interface, represented as a JSON array of BCP47 [RFC5646] language tag values.
claims_parameter_supported
OPTIONAL. Boolean value specifying whether the Platform supports use of the claims parameter, with true indicating support. If omitted, the default value is false.
request_parameter_supported
OPTIONAL. Boolean value specifying whether the Platform supports use of the request parameter, with true indicating support. If omitted, the default value is false.
request_uri_parameter_supported
OPTIONAL. Boolean value specifying whether the Platform supports use of the request_uri parameter, with true indicating support. If omitted, the default value is true.
require_request_uri_registration
OPTIONAL. Boolean value specifying whether the Platform requires any request_uri values used to be pre-registered using the request_uris registration parameter. Pre-registration is REQUIRED when the value is true. If omitted, the default value is false.
op_policy_uri
OPTIONAL. URL that the Platform provides to the person registering the Tool to read about the Platform's requirements on how the Relying Party can use the data provided by the Platform. The registration process SHOULD display this URL to the person registering the Tool if it is given.
op_tos_uri
OPTIONAL. URL that the Platform provides to the person registering the Client to read about Platform's terms of service. The registration process SHOULD display this URL to the person registering the Client if it is given.

A non-normative example response payload is given below:


HTTP/1.1 200 OK
Content-Type: application/json

{
    "issuer": "https://server.example.com",
    "authorization_endpoint":  "https://server.example.com/connect/authorize",
    "token_endpoint": "https://server.example.com/connect/token",
    "token_endpoint_auth_methods_supported": ["private_key_jwt"],
    "token_endpoint_auth_signing_alg_values_supported": ["RS256"],
    "jwks_uri": "https://server.example.com/jwks.json",
    "registration_endpoint": "https://server.example.com/connect/register",
    "scopes_supported": ["openid", 
       "https://purl.imsglobal.org/spec/lti-gs/scope/contextgroup.readonly",
       "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem",
       "https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly",
       "https://purl.imsglobal.org/spec/lti-ags/scope/score",
       "https://purl.imsglobal.org/spec/lti-reg/scope/registration"],
    "response_types_supported": ["id_token"],
    "subject_types_supported": ["public", "pairwise"],
    "id_token_signing_alg_values_supported": ["RS256", "ES256"],
    "claims_supported": ["sub", "iss", "name", "given_name", "family_name", "nickname", 
                         "picture", "email", "locale"]
}
					

The issuer value returned MUST be identical to the Issuer URL that was directly used to retrieve the configuration information. This MUST also be identical to the iss Claim value in ID Tokens issued from this Issuer.

5.5.4 Client Registration (Step 3)

This section follows the OpenID Connect Dynamic Client Registration [OPENID-DCR] specification. The tool requests a registration using the registration_endpoint advertised in the openid-configuration. As per [OPENID-DCR] Section 3, this end point should preferably be open but may be short lived; a platform may require the tool to include an initial access token in the request. If so, the registration initiation request will include the token to use for that registration request. To to guard against impersonation attacks, a tool must validate the OpenID Configuration URL using the rules described in the previous section and reject the registration request if the validation fails.

The properties of the JSON body MUST be implemented as described in the following list. 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 configuration request in order for it to be accepted by the tool. Arrays MUST be used even when a single value is to be sent. Claims with zero elements MUST be omitted from the response.

application_type
REQUIRED. Kind of the application. This MUST have a value of web.
redirect_uris
REQUIRED ARRAY. Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request, with the matching performed as described in Section 6.2.1 of [RFC3986] (Simple String Comparison).
response_types
REQUIRED ARRAY. Containing a list of the OAuth 2.0 response_type values that the Tool is declaring that it will restrict itself to using.
grant_types
REQUIRED ARRAY. The list of the OAuth 2.0 Grant Types that the Client is declaring that it will restrict itself to using. The Grant Type values used by OpenID Connect are:
  • client_credentials
  • authorization_code
  • implicit
  • implicit_token
The following table lists the correspondence between response_type values that the Tool will use and grant_type values that MUST be included in the registered grant_types list:
  • code maps to authorization_code, client_credentials
  • id_token maps to implicit, client_credentials
  • code id_token maps to implicit
  • code_token maps to authorization_code, implicit, client_credentials
  • code token id_token maps to authorization_code, implicit, client_credentials
If omitted, the default is that the Client will use only the authorization_code Grant Type.
initiate_login_uri
REQUIRED. URI using the https scheme that a third party can use to initiate a login by the Tool, as specified in Section 4 of OpenID Connect Core 1.0 [OPENID-CCORE]]. The URI MUST accept requests via both GET and POST. The Tool MUST understand the login_hint and iss parameters and SHOULD support the target_link_uri parameter.
client_name
REQUIRED. Name of the Tool to be presented to the End-User. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 of [OPENID-DCR].
jwks_uri
REQUIRED. URL for the Tool's JSON Web Key Set document. If the Tool signs requests to the Server, it contains the signing key(s) the Server uses to validate signatures from the Client. The JWK Set MAY also contain the Tool's encryption keys(s), which are used by the Server to encrypt responses to the Tool. When both signing and encryption keys are made available, a use (Key Use) parameter value is REQUIRED for all keys in the referenced JWK Set to indicate each key's intended usage. Although some algorithms allow the same key to be used for both signatures and encryption, doing so is NOT RECOMMENDED, as it is less secure.
token_endpoint_auth_method
REQUIRED. Requested Client Authentication method for the Token Endpoint. The value MUST be private_key_jwt.
scope
REQUIRED. In the registration request, this is a string containing a space-separated list of scope values that this Tool MUST include when requesting access tokens. If omitted, the authorization server MAY register a Consumer with a default set of scopes. In the registration response, this is a list of scopes the authorization server supports.
logo_uri
OPTIONAL. URL that references a logo for the Tool application. If present, the server SHOULD display this image to the End-User during approval. The value of this field MUST point to a valid image file. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 [OPENID-DCR].
contacts
OPTIONAL ARRAY. Array of e-mail addresses of people responsible for this Client. This might be used by some providers to enable a Web user interface to modify the Client information.
client_uri
OPTIONAL. URL of the home page of the Tool. The value of this field MUST point to a valid Web page. If present, the server SHOULD display this URL to the End-User in a followable fashion. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 [OPENID-DCR].
policy_uri
OPTIONAL. URL that the Tool provides to the End-User to read about how the profile data will be used. The value of this field MUST point to a valid web page. The Platform SHOULD display this URL to the End-User if it is given. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 [OPENID-DCR].
tos_uri
OPTIONAL. URL that the Tool provides to the End-User to read about the Tool's terms of service. The value of this field MUST point to a valid web page. The Platform SHOULD display this URL to the End-User if it is given. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 [OPENID-DCR].
jwks
PROHIBITED. In the 1EdTech Security Framework use of the jwks_uri property is REQUIRED and so, as defined in [OPENID-DCR], use of the jwks is PROHIBITED.
sector_identifier_uri
OPTIONAL. URL using the https scheme to be used in calculating Pseudonymous Identifiers by the Platform. The URL references a file with a single JSON array of redirect_uri values.
subject_type
OPTIONAL. Subject type requested for responses to this Tool. The subject_types_supported Discovery parameter contains a list of the supported subject_type values for this server. Valid types include pairwise and public.
id_token_signed_response_alg
OPTIONAL. JWS alg algorithm REQUIRED for signing the ID Token issued to this Tool. The value none MUST NOT be used as the ID Token alg value unless the Tool uses only Response Types that return no ID Token from the Authorization Endpoint (such as when only using the Authorization Code Flow). The default, if omitted, is RS256. The approved list of algorithms that MUST be used is given in the Best Practices. The public key for validating the signature is provided by retrieving the JWK Set referenced by the jwks_uri element from OpenID Connect Discovery 1.0 [OPENID-DIS].
id_token_encrypted_response_alg
OPTIONAL. JWE alg algorithm REQUIRED for encrypting the ID Token issued to this Tool. If this is requested, the response will be signed then encrypted, with the result being a Nested JWT, as defined in [RFC7519]. The default, if omitted, is that no encryption is performed.
id_token_encrypted_response_enc
OPTIONAL. JWE enc algorithm REQUIRED for encrypting the ID Token issued to this Client. If id_token_encrypted_response_alg is specified, the default for this value is A128CBC-HS256. When id_token_encrypted_response_enc is included, id_token_encrypted_response_alg MUST also be provided.
userinfo_signed_response_alg
OPTIONAL. JWS alg algorithm REQUIRED for signing UserInfo Responses. If this is specified, the response will be JWT [RFC7519] serialized, and signed using JWS. The default, if omitted, is for the UserInfo Response to return the Claims as a UTF-8 encoded JSON object using the application/json content-type.
userinfo_encrypted_response_alg
OPTIONAL. JWE alg algorithm REQUIRED for encrypting UserInfo Responses. If both signing and encryption are requested, the response will be signed then encrypted, with the result being a Nested JWT, as defined in [RFC7519]. The default, if omitted, is that no encryption is performed.
userinfo_encrypted_response_enc
OPTIONAL. JWE enc algorithm REQUIRED for encrypting UserInfo Responses. If userinfo_encrypted_response_alg is specified, the default for this value is A128CBC-HS256. When userinfo_encrypted_response_enc is included, userinfo_encrypted_response_alg MUST also be provided.
request_object_signing_alg
OPTIONAL. JWS alg algorithm that MUST be used for signing Request Objects sent to the Platform. All Request Objects from this Tool MUST be rejected, if not signed with this algorithm. Request Objects are described in Section 6.1 of OpenID Connect Core 1.0 [OPENID-CCORE]. This algorithm MUST be used both when the Request Object is passed by value (using the request parameter) and when it is passed by reference (using the request_uri parameter). Servers SHOULD support RS256. The value none MAY be used. The default, if omitted, is that any algorithm supported by the Platform and the Tool MAY be used.
request_object_encryption_alg
OPTIONAL. JWE alg algorithm the Tool is declaring that it may use for encrypting Request Objects sent to the Platform. This parameter SHOULD be included when symmetric encryption will be used, since this signals to the Platform that a client_secret value needs to be returned from which the symmetric key will be derived, that might not otherwise be returned. The Tool MAY still use other supported encryption algorithms or send unencrypted Request Objects, even when this parameter is present. If both signing and encryption are requested, the Request Object will be signed then encrypted, with the result being a Nested JWT, as defined in [RFC7519]. The default, if omitted, is that the RP is not declaring whether it might encrypt any Request Objects.
request_object_encryption_enc
OPTIONAL. JWE enc algorithm the Tool is declaring that it may use for encrypting Request Objects sent to the Platform. If request_object_encryption_alg is specified, the default for this value is A128CBC-HS256. When request_object_encryption_enc is included, request_object_encryption_alg MUST also be provided.
token_endpoint_auth_signing_alg
OPTIONAL. JWS alg algorithm that MUST be used for signing the JWT [RFC7519] used to authenticate the Client at the Token Endpoint for the private_key_jwt and client_secret_jwt authentication methods. All Token Requests using these authentication methods from this Client MUST be rejected, if the JWT is not signed with this algorithm. The approved list of algorithms that MUST be used is given in the Best Practices. The value none MUST NOT be used. The default, if omitted, is that any algorithm supported by the Platform and the Tool MAY be used.
default_max_age
OPTIONAL. Default Maximum Authentication Age. Specifies that the End-User MUST be actively authenticated if the End-User was authenticated longer ago than the specified number of seconds. The max_age request parameter overrides this default value. If omitted, no default Maximum Authentication Age is specified.
require_auth_time
OPTIONAL. Boolean value specifying whether the auth_time Claim in the ID Token is REQUIRED. It is REQUIRED when the value is true. If this is false, the auth_time Claim can still be dynamically requested as an individual Claim for the ID Token using the claims request parameter described in Section 5.5.1 of OpenID Connect Core 1.0 [OPENID-CCORE]. If omitted, the default value is false.
default_acr_values
OPTIONAL. Default requested Authentication Context Class Reference values. Array of strings that specifies the default acr values that the Platform is being requested to use for processing requests from this Tool, with the values appearing in order of preference. The Authentication Context Class satisfied by the authentication performed is returned as the acr Claim Value in the issued ID Token. The acr Claim is requested as a Voluntary Claim by this parameter. The acr_values_supported discovery element contains a list of the supported acr values supported by this server. Values specified in the acr_values request parameter or an individual acr Claim request override these default values.
initiate_login_uri
OPTIONAL. URI using the https scheme that a third party can use to initiate a login by the Tool, as specified in Section 4 of OpenID Connect Core 1.0 [OPENID-CCORE]. The URI MUST accept requests via both GET and POST. The Tool MUST understand the login_hint and iss parameters and SHOULD support the target_link_uri parameter.
request_uris
OPTIONAL ARRAY. The request_uri values that are pre-registered by the Tool for use at the Platform. Servers MAY cache the contents of the files referenced by these URIs and not retrieve them at the time they are used in a request. Platforms can require that request_uri values used be pre-registered with the require_request_uri_registration discovery parameter.

An HTTP POST message MUST be sent to the Client Registration Endpoint with the desired Tool configuration. The content type must be application/json. If provided by the platform, the tool must include the token as Bearer Token in the Authentication http header. A non-normative example is given below:

						
POST /connect/register HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.example.com
Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJ .

{
    "application_type": "web",
    "response_types": ["id_token"],
    "grant_types": ["implicit", "client_credentials"],
    "initiate_login_uri": "https://client.example.org/lti",
    "redirect_uris":
      ["https://client.example.org/callback",
       "https://client.example.org/callback2"],
    "client_name": "Virtual Garden",
    "client_name#ja": "バーチャルガーデン",
    "jwks_uri": "https://client.example.org/.well-known/jwks.json",
    "logo_uri": "https://client.example.org/logo.png",
    "policy_uri": "https://client.example.org/privacy",
    "policy_uri#ja": "https://client.example.org/privacy?lang=ja",
    "tos_uri": "https://client.example.org/tos",
    "tos_uri#ja": "https://client.example.org/tos?lang=ja",
    "token_endpoint_auth_method": "private_key_jwt",
    "contacts": ["ve7jtb@example.org", "mary@example.org"],
    "scope": "https://purl.imsglobal.org/spec/lti-ags/scope/score https://purl.imsglobal.org/spec/lti-nrps/scope/contextmembership.readonly"
}							
						
5.5.4.1 Successful Registration

As per [OPENID-DCR] upon successful registration of the application/json supplied information the Platform must return a response containing the newly created client_id. It then echoes the Tool configuration as recorded in the platform, which may differ from the configuration passed in the request based on the actual platform's capabilities and restrictions.

The registration response may include a Client Configuration Endpoint and a Registration Access Token to allow a Tool to read or update its configuration.

A non-normative example is:

							
{
    "client_id": "709sdfnjkds12",
    "registration_client_uri":
      "https://server.example.com/connect/register?client_id=709sdfnjkds12",
    "application_type": "web",
    "response_types": ["id_token"],
    "grant_types": ["implicit", "client_credentials"],
    "initiate_login_uri": "https://client.example.org/lti",
    "redirect_uris":
      ["https://client.example.org/callback",
       "https://client.example.org/callback2"],
    "client_name": "Virtual Garden",
    "jwks_uri": "https://client.example.org/.well-known/jwks.json",
    "logo_uri": "https://client.example.org/logo.png",
    "token_endpoint_auth_method": "private_key_jwt",
    "contacts": ["ve7jtb@example.org", "mary@example.org"],
    "scope": "https://purl.imsglobal.org/spec/lti-ags/scope/score"
}
							
5.5.4.2 Tool Registration Error Response

As per [OPENID-DCR], any configuration that cannot be registered should be rejected with a 400 Bad Request response with a JSON Object describing the error in the body.

5.5.5 Registration Completed and Activation (Step 4)

Once the registration is completed, successfully or not, the Tool should notify the Platform by sending an HTML5 Web Message [WebMessaging] indicating the window may be closed. Depending on whether the platform opened the registration in an IFrame or a new tab, either window.parent or window.opener should be called.

Refer to the relevant 1EdTech specification for the details of the corresponding messaging.

5.5.6 Client Registration Management

There will be some scenarios in which the Client registration information may need to be read, and/or changed and/or deleted. When using OpenID Connect, management of client registration information is covered in [OPENID-DCR]. Support for Client Registration Management is OPTIONAL. If a binding of an 1EdTech service specification wishes to make Client Registration Management available, the following MUST be completed:

  • The functionality MUST comply with the [OPENID-DCR] and the subset of features to be used MUST be clearly identified. For example only some of read, update and delete capabilities may be available
  • The conformance requirements, in the corresponding Conformance & Certification document, MUST state whether support for Client Registration Management is OPTIONAL or REQUIRED. Support of the features available in [OPENID-DCR] MUST be identified as either OPTIONAL or REQUIRED
  • Access to the Client Registration Management endpoints MUST be secured as per [RFC6750] (this makes use of the original registration access token)
  • The client registration management information exchange MUST be secured at the transport-layer using either TLS 1.2 or TLS 1.3.

6. Key Management

Some systems will require key management. In cases where systems use asymmetric keys, the Issuer of a JWT or access token signs it with its private key, and the recipient verifies the signature by using the Issuer's public key. The Issuer could be either a Platform or a Consumer. The system responsible for originating the message is the Issuer. The mechanisms by which keys are minted and distributed is outside the scope of this framework (see the Best Practice Recommendations). Therefore, there must be an out-of-band registration process during which access to the public keys is supplied. It should be noted that a Platform could be responsible for allocating key-sets to a Client: the integrity of the private key MUST be maintained by the accompanying distribution mechanism.

6.1 RSA Key

Where systems use RSA Keys, they MUST use SHA-256 (RS256) as a minimum as defined in [RFC7518]. Support for other algorithms is permitted but their use limits interoperability. Later versions of this framework MAY add OPTIONAL support for other algorithms.

6.2 JSON Web Key

When systems use JSON Web Keys (JWK) to represent the public key, such representations SHOULD conform to [RFC7517]: parties exchanging keys represented this way MUST use this form during key exchanges.

When using RSA keys, they MUST include the n (modulus) and e (exponent) as defined in [RFC7518] (see the key set example in Section 6.3 Key Set URL).

6.3 Key Set URL

When systems use Key Sets, they MUST provide a URL to the key set (the system responsible for supplying this URL must be identified in the corresponding 1EdTech service specification). A JWK Set is a container of one or multiple public keys identified by their key identifier ( kid key parameter). The [RFC7517] defines JWK Sets.

The supplier of the key set URL MUST use the kid parameter to identify the keys. Even when there is only one key in a key-set a kid MUST be supplied. Both a Platform and a Consumer could use key-sets.

The Issuer of a JWT identifies the key a receiver uses to validate the JWT signature by using the kid JWT header Claim. The Issuer MUST NOT reuse the kid identifier to identify different public keys of the same type (kty), allowing the public key to be cached by the Consumer. The Issuer MAY issue a cache-control: max-age HTTP header on requests to retrieve a key set to signal how long the retriever may cache the key set before refreshing it.

Here is an example of a JWK Set containing two RSA keys:


{
    "keys": [{
        "e": "AQAB",
        "use": "sig",
        "alg": "RS256",
        "kty": "RSA",
        "n": "oNqXxxWuX7LlovO5reRNau5f96K_o3DJx-wK7lrjBmp0qKwNszbbp8MvfrlVs-oYXfj1rzqAeY6GJF5BETViDTT0i2fEz37J0HGAeTrO7Z5zI5Ure9Cb0lulLOZj1hF8piZzWW_z_set2NyhafoZ-IG1NSe61mqHu7mTjuHYST84igz-bPKhkJAVlmPPjHTO51hG9T_roVIkjXnvgqd2dCaJ0ExT2bR96jcyausbkdDNfPtJdfSCAWYXGQnt0PmIysOHPtCkyFqv5ez8KXT7Q4CAYd7nxwfWNOFRHyLAyF__cYEJlBEKGyJniSIPtkGBWrbXUQhKF6TEFa-RRRl8Dw==",
        "kid": "1516918956_0"
    }, {
        "e": "AQAB",
        "use": "sig",
        "alg": "RS256",
        "kty": "RSA",
        "n": "kMfHwTp2dIYybtvU-xzF2E3dRJBNBtNbb-d3-Rm6nRUraxnTwZ6Fr1YpFBd1pnWzLzdtMv7ofCd28nx-1mfYZ6qhqPWF1RpGe2vVOSTmcu-QpA9h-rouqRKlv3jvXPn623Z2U1Wml0EIxyIzD3WLu7NkWEKSIcBzeY1TctpO5FSU3EyyCX1UoIMuvYBP9tiZlc74yIZvky-qT8Ej3S8L0JqhvD583E_uGMoLowguOl2yYr9zhubiqOxT3VsxvpJCu04TWmvf4XX34IQRyAHcPJFQ2QiBfLWvWyc6iP3JJYJvyapwc5vVEismryXnngyBX8NXHZaarMi6g5kTQi8itw==",
        "kid": "1516918956_1"
    }]
}        

The details of the permitted parameters for RSA keys is supplied in Section 6.3 of [RFC7518]. This RFC should also be used for permitted parameters when using other JSON Web Algorithms.

6.4 Issuer Public Key Rotation

When the Issuer rotates its public key, the Issuer MUST add it to the JSON Key Set under a new kid. Other parties can then download a new version of the JSON Key Set. 1EdTech recommends that Issuers doing key rotation preserve the previous public key in the JSON Key Set to allow an overlap.

If the Issuer does not use the kid parameter to identify its key, other parties using the key SHOULD use the cache-control header to properly rotate their cached copies of the key.

7. Best Practice Recommendations

Implementers should ensure that they are familiar with the OAuth 2.0 threat model and security considerations addressed in [RFC6819]. It is also RECOMMENDED that implementers are aware of the latest OAuth 2.0 security best current practices [OAUTH2-SBP] and similarly for the use of JSON Web Tokens [JSONWT-BP].

7.1 Access Token Management

7.1.1 Expires_In Values and Renewing the Access Token

The recommended value of the 'expires_in' attribute is 3600 i.e. one hour. This means that the validity of the access token expires one hour after the time it was issued. Client-credentials based OAuth 2 does NOT permit the use of access token refreshing. Therefore, once an access token has expired, a new access token MUST be requested. The same set of credentials MAY be reused when requesting a new access token. However, these credentials MAY also expire: if they expire then a request for an access token using these credentials MUST be refused. The use of expiry times for credentials is implementation dependent.

Token Refresh is permitted with Authorization Code Grant. An Authorization Server is NOT REQUIRED to support token refresh.

7.1.2 Authorization Code Details

The Authorization Code MUST be used only once. A lifetime for the authorization code of 600 seconds (10 minutes) is RECOMMENDED. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code. The authorization code is bound to the client identifier and redirection URI

7.1.3 Scope Naming Conventions

When requesting an access token it is a requirement, for access to an 1EdTech-compliant service, to identify the set of scopes for the access request. The set of scopes that are available as part of an 1EdTech service are defined in the corresponding specification document. In this document is the naming convention that SHOULD be adopted for those scopes. This naming convention is based upon a broader set of guidelines created by 1EdTech for all of its generated artifacts. The format for a scope is:

						
https://purl.imsglobal.org/spec/[shortname]/[version]/scope/[scopeleaf].[action]
        				

where:

[shortname] The abbreviated name of the service specification e.g. or for OneRoster, lti for LTI, etc.

[version] The version of the service specification e.g. v1p0, v2p1, etc.

[scopeleaf] An appropriate term for the collection of endpoints being covered by the scope.

[action] A term that reflects that nature of the scope. The suggested values are:

  • readonly for a set of endpoints that permit read only using the GET verb

  • createput for a set of endpoints that permit creation using the PUT verb

  • createpost for a set of endpoints that permit creation using the POST verb

  • update for a set of endpoints that permit changing of an established resource

  • replace for a set of endpoints that permit overwriting of an established resource

  • delete for a set of endpoints that permit delete only

  • all for access to all of endpoints supported for the version of the identified specification

An example of some scopes that have already been defined by 1EdTech are:


https://purl.imsglobal.org/spec/or/v1p2/scope/gradebook.delete          
        			

which is used in OneRoster 1.2 to permit access to the endpoints that allow a gradebook resource to be deleted, and:


https://purl.imsglobal.org/spec/rs/v1p0/scope/resource.readonly          
        			

which is used in LTI Resource Search 1.0 to permit access to the endpoints that allow access to the information about a set of resources.

7.1.4 Managing Scopes

1EdTech REQUIRES the use of scopes when obtaining an access token. The definition of the set of scopes for a service is contained within the corresponding 1EdTech specification. Therefore, an authorization server MUST be made aware of these scopes. Either the credentials or the JWT claim set supplied when requesting the access token must be used to determine if the requesting client is permitted to request access depending on those scopes. Scope definitions are immutable and permanent.

The way in which an authorization server obtains the information about the set of permitted scopes for a service is implementation dependent. An authorization server MUST support validation of scopes with respect to access token provision. A scope MUST NOT be allocated if it is not contained within the request for the access token.

The set of scopes to be used in a service are defined within the 1EdTech service specification. The specification MAY also permit the definition and use of proprietary scopes i.e. to extend the set scopes defined in the 1EdTech specification.

7.2 Approved JWT Signing Algorithms

Below is a list of approved algorithms for JWT signing. Implementations SHOULD support all of the algorithms and one of them MUST be used. The Security Committee will amend this list as appropriate. The approved set of algorithms is:

  • RS256
  • RS384
  • RS512
  • ES256 (excluding ES256K)
  • ES384
  • ES512

The justifications for this list selection are:

  • All common programming languages have at least one library that covers all of these signing algorithms. The languages that do not currently have a compatible library often have a compatible language library to do the signing. The obvious example is Groovy on the JVM for which any Groovy user has access to the Java libraries;
  • To date there are no known, successful attack vectors for RS256. However, it is getting older and theoretically an attack vector with Quantum Computers could be done in a few hours to a few days. Attacks with a traditional supercomputer would take many years (the prospects of usable data from such an attack is, at present, very low). However, new attack attempts are constantly being offered. Therefore, as a precaution RS384 and RS512 have been added as alternatives;
  • Going from RS256 to RS512 for an encryption/decryption workflow would require approximately 7 times the time to complete the same operations (on average). This is the primary reason for addition of RS384 which, in general, can achieve better protection for only about a 2 times increase in processing time. At present JWT signing does not use encryption/decryption at this time. Instead, public/private key sets are used in the signing of JWT payloads. The full effect of the increase of key size is not linear in these signing applications, so a move to RS384 or RS512 would not be anywhere as dramatic as 2x or 7x for our use in signing the payloads;
  • The addition of Elliptical Curve algorithms provides a modern version of signing that will (in general) decrease the size of each key used in signing operations. Since everyone uses one or more common libraries to do this signing, more options for cryptographic signing can be added at nearly no cost. The only known cost is that the ECXXX algorithms are marginally slower than RSXXX for verification of the same data signatures.

7.3 Key Distribution

The 1EdTech approach to message signing is based upon the use of key-pairs (private and public key) by the two end-systems i.e. the Platform and the Consumer. Whereas distribution of public keys does not require a secure mechanism, the integrity of the private keys must not be compromised. A system SHOULD NOT use a single key pair to secure message signing for more than one system. Therefore, systems SHOULD be capable of obtaining and using many key pairs and MAY use key exchange and rotation using a JWK Set and Key Set URLs to manage the use of many key pairs.

Let the private and public key pair for a Platform be denoted by { P[X], P[K] } and the equivalent for a Consumer by { C[X], C[K] }. In the case of key-sets this becomes {{ P[X1], P[K1] }, ..., { P[Xm], P[Km] }} and {{ C[X1], C[K1] }, ..., { C[Xn], C[Kn] }} i.e. the are 'm' key-pairs for the Platform and 'n' key-pairs for the Consumer. Knowledge of the public keys, P[K1]..P[Km] and C[K1]..C[Kn] is unrestricted. Knowledge of the private keys SHOULD be as restricted as much as possible. For a Platform/Consumer pair the keys can be created by:

Platform only. The Platform creates both sets of key-pairs. The Platform is responsible for providing the Consumer with its keys i.e. the Platform creates all of the keys and MUST securely give the Consumer the keys {{ C[X1], C[K1] }, ..., { C[Xn], C[Kn] }}. The Consumer must also be given the Platform's public keys i.e. { P[K1]..P[Km] }. The advantage of this approach is that the Consumer is not burdened with key creation and distribution.

Consumer only. The Consumer creates both sets of key-pairs. The Consumer is responsible for providing the Platform with the private key i.e. the Consumer creates all of the keys and MUST securely give the Platform the keys {{ P[X1], P[K1] }, ..., { P[Xn], P[Km] }}. The Platform must also be given the Client's public keys i.e. { C[K1]..C[Kn] }. The disadvantage of this approach is that the Platform is dependent upon the Consumer creating sufficiently robust keys and for ensuring the integrity of these keys is not compromised.

Platform and Consumer Independently. Each system creates their on key pairs. Each system is responsible for making the other aware of the public keys. The advantage of this approach is that only the user of the private keys has knowledge of those keys. The disadvantage is that the Consumer functionality is more complex.

In general, there will be many more Consumers than Platforms. It is important to minimise the implementation effort required to achieve the required message signing. This security framework is based upon security standards that have broad adoption. Key generation and distribution between Platforms and Consumers has not been defined. The ways in which key distribution is managed within a Consumer is dependent on:

  • The business model used for the provision of access to the Consumer. The distribution modes for the Consumer itself will indicate the best ways to manage the corresponding allocation of private keys and access to the relevant public keys;

  • The key distribution models that become preferred by the Platforms. For educational technology this will be determined by the approaches required by learning management systems and/or student information systems.

New requirements and recommendations MAY be made in a later version of this framework, if, at some later date, there is a clarification, in the education technology marketplace, on the preferred mechanism for key distribution.

7.4 Handling Security Vulnerabilities

7.4.1 Prohibiting the Login CSRF Vulnerability

For Platform initiated message exchanges the combination of the full six steps of the 'Implicit Flow' with the 'Initiating Login from a Third Party' mechanisms of the [OPENID-CCORE] prevents vulnerability to Login CSRF attacks. This vulnerability does NOT occur in Tool initiated exchanges because the user is already logged into the platform. The Platform must verify that the data claim returned in the Tool initiated message was generated by the current user’s session in a corresponding Tool launch.

7.4.2 Symmetric vs. Asymmetric Keys with JWT

The primary difference between the use of Symmetric and Asymmetric keys is that the same key is used in both end-systems when using Symmetric keys. When using Asymmetric keys the end-systems have their own public and private key pairs. 1EdTech RECOMMENDS the use of Asymmetric keys. If symmetric keys are used then the associated 1EdTech service specification MUST explain and justify why that approach has been adopted. Asymmetric key usage should reduce a system's vulnerability but the overall vulnerability of a system is based upon the combination of many issues.

7.5 Miscellaneous

7.5.1 Handling Clock Drift

Clock drift refers to several related phenomena where a clock does not run at exactly the same rate as a reference clock (see Wikipedia). Therefore, after some time the clock "drifts apart" or gradually desynchronizes from the other clock. All clocks are subject to drift, causing eventual divergence unless resynchronized.

Accurate clock alignment is important whenever absolute time-based data exchanges are used. It is recommended that a margin of error of less than or equal to 300s is used to compensate for clock drift. In many cases this margin should be much smaller e.g. less than 5% of the maximum time period being used.

A. Service Description Documents Using OpenAPI

OpenAPI formatted files are used by Service Providers to distribute information about the configuration of the services being supplied. An example is the OpenAPI 3.0 (JSON) file supplied as part of the OneRoster 1.2 specification (Resources Service). Below is a listing of that file.

				
{
    "openapi" : "3.0.0",
    "info" : {
        "version" : "1.2",
        "title" : "OneRoster Resources OpenAPI (JSON) Definition",
        "description" : "The OneRoster 1.2 Resources service in REST/JSON",
        "termsOfService" : "https://www.imsglobal.org/license.html",
        "contact" : {
            "name" : "Lisa Mattson (COO), 1EdTech ",
            "url" : "http://www.imsglobal.org",
            "email" : "lmattson@imsglobal.org"
        },
        "license" : {
            "name" : "1EdTech",
            "url" : "https://www.imsglobal.org/license.html"
        }
    },
    "servers" : [
        {
            "url" : "https://www.imsglobal.org/ims/oneroster/resources/v1p2",
            "description" : "Server URL should be changed to the actual server location."
        }
    ],
    "tags" : [
        {
            "name" : "ClassesManagement",
            "description" : "The allocation of resources to classes. "
        },
        {
            "name" : "CoursesManagement",
            "description" : "The allocation of resources to courses. "
        },
        {
            "name" : "ResourcesManagement",
            "description" : "Management of information about resources."
        },
        {
            "name" : "UsersManagement",
            "description" : "The allocation of resources to courses. "
        }
    ],
    "paths" : {
        "/classes/{classSourcedId}/resources" : {
            "get" : {
                "operationId" : "getResourcesForClass",
                "summary" : "Read request message for the getResourcesForClass() API call.",
                "tags" : [ "ClassesManagement" ],
                "parameters" : [
                    {
                        "name" : "classSourcedId",
                        "in" : "path",
                        "required" : true,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "simple"
                    },
                    {
                        "name" : "limit",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 100,
                            "minimum" : 1
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "offset",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 0,
                            "minimum" : 0
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "sort",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "orderBy",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string",
                            "enum" : [ "asc","desc" ]
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "filter",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/ResourceSetDType"
                                }
                            }
                        },
                        "headers" : {
                            "X-Total-Count" : {
                                "schema" : {
                                    "type" : "integer"
                                }
                            }
                        },
                        "links" : {
                            "next" : {
                                "operationId" : "getResourcesForClass",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "last" : {
                                "operationId" : "getResourcesForClass",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "first" : {
                                "operationId" : "getResourcesForClass",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "prev" : {
                                "operationId" : "getResourcesForClass",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/courses/{courseSourcedId}/resources" : {
            "get" : {
                "operationId" : "getResourcesForCourse",
                "summary" : "Read request message for the getResourcesForCourse() API call.",
                "tags" : [ "CoursesManagement" ],
                "description" : "...",
                "parameters" : [
                    {
                        "name" : "courseSourcedId",
                        "in" : "path",
                        "required" : true,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "simple"
                    },
                    {
                        "name" : "limit",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 100,
                            "minimum" : 1
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "offset",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 0,
                            "minimum" : 0
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "sort",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "orderBy",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string",
                            "enum" : [ "asc","desc" ]
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "filter",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/ResourceSetDType"
                                }
                            }
                        },
                        "headers" : {
                            "X-Total-Count" : {
                               "schema" : {
                                    "type" : "integer"
                                }
                            }
                        },
                        "links" : {
                            "next" : {
                                "operationId" : "getResourcesForCourse",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "last" : {
                                "operationId" : "getResourcesForCourse",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "first" : {
                                "operationId" : "getResourcesForCourse",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "prev" : {
                                "operationId" : "getResourcesForCourse",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/resources" : {
            "get" : {
                "operationId" : "getAllResources",
                "summary" : "Read request message for the getAllResources() API call.",
                "tags" : [ "ResourcesManagement" ],
                "parameters" : [
                    {
                        "name" : "limit",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 100,
                            "minimum" : 1
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "offset",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 0,
                            "minimum" : 0
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "sort",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "orderBy",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string",
                            "enum" : [ "asc","desc" ]
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "filter",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly",
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/ResourceSetDType"
                                }
                            }
                        },
                        "headers" : {
                            "X-Total-Count" : {
                                "schema" : {
                                    "type" : "integer"
                                }
                            }
                        },
                        "links" : {
                            "next" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "last" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "first" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "prev" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/resources/{sourcedId}" : {
            "get" : {
                "operationId" : "getResource",
                "summary" : "Read request message for the getResource() API call.",
                "tags" : [ "ResourcesManagement" ],
                "parameters" : [
                    {
                        "name" : "sourcedId",
                        "in" : "path",
                        "description" : "...",
                        "required" : true,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "simple"
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly",
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/SingleResourceDType"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/users/{userSourcedId}/resources" : {
            "get" : {
                "operationId" : "getResourcesForUser",
                "summary" : "Read request message for the getResourcesForUser() API call.",
                "tags" : [ "UsersManagement" ],
                "parameters" : [
                    {
                        "name" : "userSourcedId",
                        "in" : "path",
                        "required" : true,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "simple"
                    },
                    {
                        "name" : "limit",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 100,
                            "minimum" : 1
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "offset",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 0,
                            "minimum" : 0
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "sort",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "orderBy",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string",
                            "enum" : [ "asc","desc" ]
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "filter",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/ResourceSetDType"
                                }
                            }
                        },
                        "headers" : {
                            "X-Total-Count" : {
                                "schema" : {
                                    "type" : "integer"
                                }
                            }
                        },
                        "links" : {
                            "next" : {
                                "operationId" : "getResourcesForUser",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "last" : {
                                "operationId" : "getResourcesForUser",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "first" : {
                                "operationId" : "getResourcesForUser",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "prev" : {
                                "operationId" : "getResourcesForUser",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components" : {
        "securitySchemes" : {
            "OAuth2CC" : {
                "type" : "oauth2",
                "flows" : {
                    "clientCredentials" : {
                        "tokenUrl" : "https://www.imsglobal.org",
                        "scopes" : {
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource.readonly" : "To enable access to ALL of the endpoints for the resources service.",
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly" : "The core set of scopes to enable information about all resources or a single resource to be obtained."
                        }
                    }
                }
            }
        },
        "schemas" : {
            "MetadataDType" : {
                "type" : "object",
                "properties" : {

                },
                "additionalProperties" : true
            },
            "ResourceDType" : {
                "type" : "object",
                "properties" : {
                    "sourcedId" : {
                        "type" : "string"
                    },
                    "status" : {
                        "type" : "string",
                        "enum" : [ "active","tobedeleted" ]
                    },
                    "dateLastModified" : {
                        "type" : "string",
                        "format" : "date-time"
                    },
                    "metadata" : {
                        "$ref" : "#/components/schemas/MetadataDType"
                    },
                    "title" : {
                        "type" : "string"
                    },
                    "roles" : {
                        "type" : "array",
                        "minItems" : 0,
                        "items" : {
                            "anyOf" : [
                                {
                                    "type" : "string",
                                    "enum" : [ "administrator","aide","guardian","parent","proctor","relative","student","teacher" ]
                                },
                                {
                                    "type" : "string",
                                    "pattern" : "(ext:)[a-zA-Z0-9\\.\\-_]+"
                                }
                            ]
                        }
                    },
                    "importance" : {
                        "type" : "string",
                        "enum" : [ "primary","secondary" ]
                    },
                    "vendorResourceId" : {
                        "type" : "string"
                    },
                    "vendorId" : {
                        "type" : "string"
                    },
                    "applicationId" : {
                        "type" : "string"
                    }
                },
                "required" : [ "sourcedId","status","dateLastModified","vendorResourceId" ],
                "additionalProperties" : false
            },
            "ResourceSetDType" : {
                "type" : "object",
                "properties" : {
                    "resources" : {
                        "type" : "array",
                        "minItems" : 0,
                        "items" : {
                            "$ref" : "#/components/schemas/ResourceDType"
                        }
                    }
                },
                "additionalProperties" : false
            },
            "SingleResourceDType" : {
                "type" : "object",
                "properties" : {
                    "resource" : {
                        "$ref" : "#/components/schemas/ResourceDType"
                    }
                },
                "required" : [ "resource" ],
                "additionalProperties" : false
            },
            "imsx_CodeMinorDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMinorField" : {
                        "type" : "array",
                        "minItems" : 1,
                        "items" : {
                            "$ref" : "#/components/schemas/imsx_CodeMinorFieldDType"
                        }
                    }
                },
                "required" : [ "imsx_codeMinorField" ],
                "additionalProperties" : false
            },
            "imsx_CodeMinorFieldDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMinorFieldName" : {
                        "type" : "string",
                        "default" : "TargetEndSystem"
                    },
                    "imsx_codeMinorFieldValue" : {
                        "type" : "string",
                        "enum" : [ "fullsuccess","invalid_filter_field","invalid_selection_field","forbidden","unauthorisedrequest","internal_server_error","server_busy","unknownobject","invaliddata" ]
                    }
                },
                "required" : [ "imsx_codeMinorFieldName","imsx_codeMinorFieldValue" ],
                "additionalProperties" : false
            },
            "imsx_StatusInfoDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMajor" : {
                        "type" : "string",
                        "enum" : [ "success","processing","failure","unsupported" ]
                    },
                    "imsx_severity" : {
                        "type" : "string",
                        "enum" : [ "status","warning","error" ]
                    },
                    "imsx_description" : {
                        "type" : "string"
                    },
                    "imsx_CodeMinor" : {
                        "$ref" : "#/components/schemas/imsx_CodeMinorDType"
                    }
                },
                "required" : [ "imsx_codeMajor","imsx_severity" ],
                "additionalProperties" : false
            }
        }
    }
}
				

An example of the profiled version specific to a deployment of the service is given below. The changes are:

  • The number of 'paths' has been reduced to the 'getAllResources()' and 'getResource()';
  • The set of 'tags' has been reduced to 'Resources management';
  • The available 'scopes' has been reduced to core access;
  • The set of corporate information has been changed to 'NewCo';
  • The 'servers' value has been changed to 'https://www.newco/sisserviceprovider/ims/oneroster/resources/v1p2';
  • A new property (extnc:language) has been added to the MetaDataDType' class definition under the 'schemas';
  • The Dynamic Client Registration URL has been added in the OAuth 2 client credentials definition in the 'securitySchemes'.
				
{
    "openapi" : "3.0.0",
    "info" : {
        "version" : "1.2",
        "title" : "NewCo OneRoster Resources OpenAPI (JSON) Definition",
        "description" : "The NewCo OneRoster 1.2 Resources Service Provision",
        "termsOfService" : "https://www.newco.com/license.html",
        "contact" : {
            "name" : "Lisa Boss (COO), NewCo",
            "url" : "http://www.newco.com",
            "email" : "lboss@newco.com"
        },
        "license" : {
            "name" : "NewCo",
            "url" : "https://www.newco.com/license.html"
        }
    },
    "servers" : [
        {
            "url" : "https://www.newco/sisserviceprovider/ims/oneroster/resources/v1p2",
            "description" : "Server URL."
        }
    ],
    "tags" : [
        {
            "name" : "ResourcesManagement",
            "description" : "Management of information about resources."
        }
    ],
    "paths" : {
        "/resources" : {
            "get" : {
                "operationId" : "getAllResources",
                "summary" : "Read request message for the getAllResources() API call.",
                "tags" : [ "ResourcesManagement" ],
                "parameters" : [
                    {
                        "name" : "limit",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 100,
                            "minimum" : 1
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "offset",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "integer",
                            "format" : "int32",
                            "default" : 0,
                            "minimum" : 0
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "sort",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "orderBy",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string",
                            "enum" : [ "asc","desc" ]
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "filter",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/ResourceSetDType"
                                }
                            }
                        },
                        "headers" : {
                            "X-Total-Count" : {
                                "schema" : {
                                    "type" : "integer"
                                }
                            }
                        },
                        "links" : {
                            "next" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "last" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "first" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            },
                            "prev" : {
                                "operationId" : "getAllResources",
                                "parameters" : {
                                    "limit" : "$request.path.limit",
                                    "offset" : "$request.path.offset"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/resources/{sourcedId}" : {
            "get" : {
                "operationId" : "getResource",
                "summary" : "Read request message for the getResource() API call.",
                "tags" : [ "ResourcesManagement" ],
                "parameters" : [
                    {
                        "name" : "sourcedId",
                        "in" : "path",
                        "description" : "...",
                        "required" : true,
                        "schema" : {
                            "type" : "string"
                        },
                        "style" : "simple"
                    },
                    {
                        "name" : "fields",
                        "in" : "query",
                        "required" : false,
                        "schema" : {
                            "type" : "array",
                            "items" : {
                                "type" : "string"
                            }
                        },
                        "style" : "form",
                        "allowEmptyValue" : false
                    }
                ],
                "security" : [
                    {
                        "OAuth2CC" : [
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly"
                        ]
                    }
                ],
                "responses" : {
                    "200" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/SingleResourceDType"
                                }
                            }
                        }
                    },
                    "400" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "401" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "403" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "404" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "422" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "429" : {
                       "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "500" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    },
                    "default" : {
                        "content" : {
                            "application/json" : {
                                "schema" : { 
                                	"$ref" : "#/components/schemas/imsx_StatusInfoDType"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components" : {
        "securitySchemes" : {
            "OAuth2CC" : {
                "type" : "oauth2",
                "x-imssf-registrationUrl" : "newco.com/drcservice/registration",
                "flows" : {
                    "clientCredentials" : {
                        "tokenUrl" : "https://www.imsglobal.org",
                        "scopes" : {
                            "http://purl.imsglobal.org/spec/or/v1p2/scope/resource-core.readonly" : "The core set of scopes to enable information about all resources or a single resource to be obtained."
                        }
                    }
                }
            }
        },
        "schemas" : {
            "MetadataDType" : {
                "type" : "object",
                "properties" : {
					"extnc:language" : {
						"type" : "string"
					}
                },
                "additionalProperties" : true
            },
            "ResourceDType" : {
                "type" : "object",
                "properties" : {
                    "sourcedId" : {
                        "type" : "string"
                    },
                    "status" : {
                        "type" : "string",
                        "enum" : [ "active","tobedeleted" ]
                    },
                    "dateLastModified" : {
                        "type" : "string",
                        "format" : "date-time"
                    },
                    "metadata" : {
                        "$ref" : "#/components/schemas/MetadataDType"
                    },
                    "title" : {
                        "type" : "string"
                    },
                    "roles" : {
                        "type" : "array",
                        "minItems" : 0,
                        "items" : {
                            "anyOf" : [
                                {
                                    "type" : "string",
                                    "enum" : [ "administrator","aide","guardian","parent","proctor","relative","student","teacher" ]
                                },
                                {
                                    "type" : "string",
                                    "pattern" : "(ext:)[a-zA-Z0-9\\.\\-_]+"
                                }
                            ]
                        }
                    },
                    "importance" : {
                        "type" : "string",
                        "enum" : [ "primary","secondary" ]
                    },
                    "vendorResourceId" : {
                        "type" : "string"
                    },
                    "vendorId" : {
                        "type" : "string"
                    },
                    "applicationId" : {
                        "type" : "string"
                    }
                },
                "required" : [ "sourcedId","status","dateLastModified","vendorResourceId" ],
                "additionalProperties" : false
            },
            "ResourceSetDType" : {
                "type" : "object",
                "properties" : {
                    "resources" : {
                        "type" : "array",
                        "minItems" : 0,
                        "items" : {
                            "$ref" : "#/components/schemas/ResourceDType"
                        }
                    }
                },
                "additionalProperties" : false
            },
            "SingleResourceDType" : {
                "type" : "object",
                "properties" : {
                    "resource" : {
                        "$ref" : "#/components/schemas/ResourceDType"
                    }
                },
                "required" : [ "resource" ],
                "additionalProperties" : false
            },
            "imsx_CodeMinorDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMinorField" : {
                        "type" : "array",
                        "minItems" : 1,
                        "items" : {
                            "$ref" : "#/components/schemas/imsx_CodeMinorFieldDType"
                        }
                    }
                },
                "required" : [ "imsx_codeMinorField" ],
                "additionalProperties" : false
            },
            "imsx_CodeMinorFieldDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMinorFieldName" : {
                        "type" : "string",
                        "default" : "TargetEndSystem"
                    },
                    "imsx_codeMinorFieldValue" : {
                        "type" : "string",
                        "enum" : [ "fullsuccess","invalid_filter_field","invalid_selection_field","forbidden","unauthorisedrequest","internal_server_error","server_busy","unknownobject","invaliddata" ]
                    }
                },
                "required" : [ "imsx_codeMinorFieldName","imsx_codeMinorFieldValue" ],
                "additionalProperties" : false
            },
            "imsx_StatusInfoDType" : {
                "type" : "object",
                "properties" : {
                    "imsx_codeMajor" : {
                        "type" : "string",
                        "enum" : [ "success","processing","failure","unsupported" ]
                    },
                    "imsx_severity" : {
                        "type" : "string",
                        "enum" : [ "status","warning","error" ]
                    },
                    "imsx_description" : {
                        "type" : "string"
                    },
                    "imsx_CodeMinor" : {
                        "$ref" : "#/components/schemas/imsx_CodeMinorDType"
                    }
                },
                "required" : [ "imsx_codeMajor","imsx_severity" ],
                "additionalProperties" : false
            }
        }
    }
}
				

B. Summary of Changes Made with Respect to Core Standards

The following changes have been made to the base specifications and standards when adopted in this Security Framework.

B.1 RFC 6749 - The OAuth 2.0 Authorization Framework

  • Use of Scopes in the Client Credentials Grant - in [RFC6749] use of the scope parameter is OPTIONAL when requesting an access token. In the 1EdTech Security Framework the scope parameter is REQUIRED. A request without inclusion of the scope parameter MUST be rejected. This change was made to impose greater control and to avoid the default condition in which lack of scoping implied full access;
  • Use of Scopes in the Authorization Code Grant - in [RFC6749] use of the scope parameter is OPTIONAL when requesting an access token. In the 1EdTech Security Framework the scope parameter is REQUIRED. A request without inclusion of the scope parameter MUST be rejected. This change was made to impose greater control and to avoid the default condition in which lack of scoping implied full access;
  • Use of Scopes for Token Refresh in the Authorization Code Grant - in [RFC6749] use of the scope parameter is OPTIONAL when refreshing an access token. In the 1EdTech Security Framework the scope parameter is REQUIRED. A refresh without inclusion of the scope parameter MUST be rejected. This change was made to impose greater control and to avoid the default condition in which lack of scoping implied full access;
  • Use of State in Authorization Code Grant - in [RFC6749] use of the state parameter is RECOMMENDED when making the authorization code request. In the 1EdTech Security Framework the state parameter is REQUIRED. A request without inclusion of the state parameter MUST be rejected. This change was made to prevent cross-site request forgery.

B.2 RFC 7591 - Dynamic Client Registration

The following changes have been made, in the Security Framework document, with respect to the properties used in a registration request ([RFC7591] Section 2):

  • Client Name - in [RFC7591] use of the client_name property is RECOMMENDED. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • Client URI - in [RFC7591] use of the client_uri property is RECOMMENDED. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • TOS URI - in [RFC7591] use of the tos_uri property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • Policy URI - in [RFC7591] use of the policy_uri property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • Software ID - in [RFC7591] use of the software_id property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • Software Version - in [RFC7591] use of the software_version property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in both the Client Registration request and response messages.
  • Use of the OPTIONAL token_endpoint_auth_method property - in the Security Framework the permitted value space has been reduced to client_secret_basic ONLY.
  • Use of the OPTIONAL grant_types property - in the Security Framework the permitted value space has been reduced to client_credentials, authorization_code or refresh_token ONLY. The default value remains as authorization_code.
  • Use of the OPTIONAL response_types property - in the Security Framework the permitted value space has been reduced to code ONLY.

The following changes have been made, in the Security Framework document, with respect to the properties used in a registration response message ([RFC7591] Section 3.2):

  • Client Secret - in [RFC7591] use of the client_secret property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in the Client Registration response messages.
  • Client Id Issued At - in [RFC7591] use of the client_id_issued_at property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED in the Client Registration response messages.
  • Client Secret Expires At - in [RFC7591] use of the client_secret_expires_at property is REQUIRED if the client_secret property is issued. Therefore, in the 1EdTech Security Framework this property is REQUIRED in the Client Registration response messages.

B.3 OpenID Connect Discovery 1.0

The following changes have been made, in the Security Framework document, with respect to the properties used in a registration configuration request for a Platform ([OPENID-DIS] Section 3):

  • Use of the registration_endpoint property is RECOMMENDED. In the 1EdTech Security Framework this property is REQUIRED.
  • Use of the userinfo_endpoint property is RECOMMENDED. In the 1EdTech Security Framework this property is OPTIONAL.
  • Use of the scopes_supported property is RECOMMENDED. In the 1EdTech Security Framework this property is REQUIRED.
  • For the response_types_supported property the values code, id_token and token_id_token MUST be supported. In the 1EdTech Security Framework only the id_token MUST be supported.
  • Use of the token_endpoint_auth_methods_supported property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED and MUST contain the value private_key_jwt.
  • Use of the token_endpoint_auth_signing_alg_values_supported property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED and MUST contain the value RS256.
  • Use of the claims_supported property is RECOMMENDED. In the 1EdTech Security Framework this property is REQUIRED.
  • OPTIONAL use of the authorization_server property has been added in the 1EdTech Security Framework.

B.4 OpenID Connect Dynamic Client Registration 1.0

The following changes have been made, in the Security Framework document, with respect to the properties used in a registration configuration request for a Tool ([OPENID-DCR] Section 3):

  • Use of the application_type property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED and it MUST have the value web.
  • Use of the response_types property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED.
  • Use of the response_types property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED. The range of permitted values has been extended to include the value client_credentials. The value of implicit MUST only be used in the context of the OpenID exchanges.
  • Use of the initiate_login_uri property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED.
  • Use of the client_name property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED.
  • Use of the jwks_uri property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED. Therefore, use of the jwks property is PROHIBITED.
  • Use of the token_endpoint_auth_method property is OPTIONAL. In the 1EdTech Security Framework this property is REQUIRED and the value MUST be set as private_key_jwt.
  • In the 1EdTech Security Framework use of the new scope property has been added and is REQUIRED.

C. Relevant Standards Summaries

C.1 Relevant Request for Comments

C.1.1 RFC 2616 - HyperText Transfer Protocol

The Hypertext Transfer Protocol (HTTP/1.1) [RFC2616] is an application-level protocol for distributed, collaborative, hypermedia information systems. It is a generic, stateless, protocol that can be used for many tasks beyond its use for hypertext, such as name servers and distributed object management systems, through extension of its request methods, error codes and headers. A feature of HTTP is the typing and negotiation of data representation, allowing systems to be built independently of the data being transferred. HTTP has been in use by the World-Wide Web global information initiative since 1990. This specification defines the protocol referred to as “HTTP/1.1”, and is an update to [RFC2068].

This document is available at: https://tools.ietf.org/pdf/rfc2616.pdf.

C.1.2 RFC 2617 - HTTP Authentication: Basic and Digest Access Authentication

"HTTP/1.0", includes the specification for a Basic Access Authentication scheme [RFC2617]. This scheme is not considered to be a secure method of user authentication (unless used in conjunction with some external secure system such as SSL), as the user name and password are passed over the network as clear text.

This document also provides the specification for HTTP’s authentication framework: the original Basic authentication scheme, and a scheme based on cryptographic hashes referred to as "Digest Access Authentication". It is, therefore, also intended to serve as a replacement for [RFC2069]. Some optional elements specified by RFC 2069 have been removed from this specification due to problems found since its publication; other new elements have been added for compatibility--those new elements have been made optional, but are strongly recommended.

Like Basic authentication, Digest Access authentication verifies that both parties to a communication know a shared secret (a password); unlike Basic authentication, this verification can be done without sending the password in the clear, which is Basic authentication’s biggest weakness. As with most other authentication protocols, the greatest sources of risks are usually found not in the core protocol itself but in policies and procedures surrounding its use.

This document is available at: https://tools.ietf.org/pdf/rfc2617.pdf.

C.1.3 RFC 4949 - Internet Security Glossary Version 2

This Glossary provides definitions, abbreviations, and explanations of terminology for information system security [RFC4949]. The 334 pages of entries offer recommendations to improve the comprehensibility of written material that is generated in the Internet Standards Process [RFC2026]. The recommendations follow the principles that such writing should follow these guidelines:

a. Use the same term or definition whenever the same concept is mentioned.

b. Use terms in their plainest, dictionary sense.

c. Use terms that are already well-established in open publications.

d. Avoid terms that either favor a particular vendor or favor a particular technology or mechanism over other, competing techniques that already exist or could be developed.

This document is both a major revision and a major expansion of the original Internet Security Glossary [RFC2828]. This revised Glossary is an extensive reference that should help the Internet community to improve the clarity of documentation and discussion in an important area of Internet technology. However, readers should be aware of the following points:

a. The recommendations and some particular interpretations in definitions are those of the author, not an official IETF position. The IETF has not taken a formal position either for or against recommendations made by this Glossary, and the use of [RFC2119] language (e.g. SHOULD NOT) in the Glossary must be understood as unofficial. In other words, the usage rules, wording interpretations, and other recommendations that the Glossary offers are personal opinions of the Glossary’s author. Readers must judge for themselves whether or not to follow his recommendations, based on their own knowledge combined with the reasoning presented in the Glossary.

b. The Glossary is rich in the history of early network security work, but it may be somewhat incomplete in describing recent security work, which has been developing rapidly.

This document is available at: https://tools.ietf.org/pdf/rfc4949.pdf.

C.1.4 RFC 5246 - The Transport Layer Security Protocol Version 1.2

This document specifies Version 1.2 of the Transport Layer Security (TLS) protocol [RFC5246]. The TLS protocol provides communications security over the Internet. The protocol allows client/server applications to communicate in a way that is designed to prevent eavesdropping, tampering, or message forgery.

This document is available at: https://tools.ietf.org/pdf/rfc5246.pdf.

C.1.5 RFC 5849 - The OAuth 1.0 Protocol

OAuth provides a method for clients to access server resources on behalf of a resource owner (such as a different Client or an end user). It also provides a process for end-users to authorize third-party access to their server resources without sharing their credentials (typically, a username and password pair), using user-agent redirections.

Use of OAuth 1.0 [RFC5849] within the context of 1EdTech specifications is deprecated. The material in this document explains the security mechanisms that MUST be used to replace OAuth 1.0.

This document is available at: https://tools.ietf.org/pdf/rfc5849.pdf.

C.1.6 RFC 6749 - The OAuth 2.0 Authorization Framework

The OAuth 2.0 authorization framework enables a third-party application to obtain limited access to an HTTP service, either on behalf of a resource owner by orchestrating an approval interaction between the resource owner and the HTTP service, or by allowing the third-party application to obtain access on its own behalf. This specification [RFC6749] replaces and obsoletes the OAuth 1.0 protocol described in [RFC5849].

This document is available at: https://tools.ietf.org/pdf/rfc6749.pdf.

C.1.7 RFC 6750 - The OAuth 2.0 Authorization Framework Bearer Token Usage

This specification describes how to use bearer tokens in HTTP requests to access OAuth 2.0 protected resources. Any party in possession of a bearer token (a "bearer") can use it to get access to the associated resources (without demonstrating possession of a cryptographic key). To prevent misuse, bearer tokens need to be protected from disclosure in storage and in transport [RFC6750].

This document is available at: https://tools.ietf.org/pdf/rfc6750.pdf.

C.1.8 RFC 6819 - OAuth 2.0 Threat Model and Security Considerations

This document gives additional security considerations for OAuth, beyond those in the OAuth 2.0 specification, based on a comprehensive threat model for the OAuth 2.0 protocol.

This document is available at: https://tools.ietf.org/pdf/rfc6819.pdf.

C.1.9 RFC 7009 - OAuth 2.0 Token Revocation

This document proposes an additional endpoint for OAuth authorization servers, which allows clients to notify the authorization server that a previously obtained refresh or access token is no longer needed. This allows the authorization server to clean up security credentials. A revocation request will invalidate the actual token and, if applicable, other tokens based on the same authorization grant.

This document is available at: https://tools.ietf.org/pdf/rfc7009.pdf.

C.1.10 RFC 7515 - JSON Web Signature (JWS)

JSON Web Signature (JWS) represents content secured with digital signatures or Message Authentication Codes (MACs) using JSON-based data structures [RFC7515]. Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and an IANA registry defined by that specification. Related encryption capabilities are described in the separate JSON Web Encryption (JWE) specification.

This document is available at: https://tools.ietf.org/pdf/rfc7515.pdf.

C.1.11 RFC 7517 - JSON Web Key

A JSON Web Key (JWK) is a JavaScript Object Notation (JSON) data structure that represents a cryptographic key. This specification also defines a JWK Set JSON data structure that represents a set of JWKs [RFC7517]. Cryptographic algorithms and identifiers for use with this specification are described in the separate JSON Web Algorithms (JWA) specification and IANA registries established by that specification.

This document is available at: https://tools.ietf.org/pdf/rfc7517.pdf.

C.1.12 RFC 7518 - JSON Web Algorithms

This specification registers cryptographic algorithms and identifiers to be used with the JSON Web Signature (JWS), JSON Web Encryption (JWE), and JSON Web Key (JWK) specifications [RFC7518]. It defines several IANA registries for these identifiers.

This document is available at: https://tools.ietf.org/pdf/rfc7518.pdf.

C.1.13 RFC 7519 - JSON Web Token

A JWT is a compact, URL-safe means of representing Claims to be transferred between two parties. The Claims in a JWT are encoded as a JSON object that is used as the payload of a JSON Web Signature (JWS) structure or as the plaintext of a JSON Web Encryption (JWE) structure, enabling the Claims to be digitally signed or integrity protected with a Message Authentication Code (MAC) and/or encrypted [RFC7519].

This document is available at: https://tools.ietf.org/pdf/rfc7519.pdf.

C.1.14 RFC 7523 - JSON Web Token Profile for OAuth 2.0 Client Authentication and Authorization Grants

This specification defines the use of a JWT bearer token as a means for requesting an OAuth 2.0 access token as well as for client authentication [RFC7523].

This document is available at: https://tools.ietf.org/pdf/rfc7523.pdf.

C.1.15 RFC 7591 - OAuth 2.0 Dynamic Client Registration Protocol

This specification defines mechanisms for dynamically registering OAuth 2.0 clients with authorization servers. Registration requests send a set of desired client metadata values to the authorization server. The resulting registration responses return a client identifier to use at the authorization server and the client metadata values registered for the client. The client can then use this registration information to communicate with the authorization server using the OAuth 2.0 protocol. This specification also defines a set of common client metadata fields and values for clients to use during registration.

This document is available at: https://tools.ietf.org/pdf/rfc7591.pdf.

C.1.16 RFC 7592 - OAuth 2.0 Dynamic Client Registration Management Protocol

This specification defines methods for management of OAuth 2.0 dynamic client registrations for use cases in which the properties of a registered client may need to be changed during the lifetime of the client. Not all authorization servers supporting dynamic client registration will support these management methods.

This document is available at: https://tools.ietf.org/pdf/rfc7592.pdf.

C.1.17 RFC 7636 - Proof Key for Code Exchange by OAuth Public Clients

OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack. This specification describes the attack as well as a technique to mitigate against the threat through the use of Proof Key for Code Exchange (PKCE, pronounced "pixy").

This document is available at: https://tools.ietf.org/pdf/rfc7636.pdf.

C.1.18 RFC 8446 - The Transport Layer Security (TLS) Protocol Version 1.3

This document specifies version 1.3 of the Transport Layer Security (TLS) protocol. TLS allows client/server applications to communicate over the Internet in a way that is designed to prevent eavesdropping, tampering, and message forgery.

This document updates RFCs 5705 and 6066, and obsoletes RFCs 5077, 5246, and 6961. This document also specifies new requirements for TLS 1.2 implementations.

This document is available at: https://tools.ietf.org/html/rfc8446.

C.2 Relevant Other Standards

C.2.1 OpenID Connect Core

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the end user based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the end user in an interoperable and REST-like manner. This specification defines the core OpenID Connect functionality: authentication built on top of OAuth 2.0 and the use of Claims to communicate information about the end user. It also describes the security and privacy considerations for using OpenID Connect [OPENID-CCORE].

This document is available at: http://openid.net/specs/openid-connect-core-1_0.html.

C.2.2 OpenID Connect Dynamic Client Registration

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner. This specification defines how an OpenID Connect Relying Party can dynamically register with the End-User's OpenID Provider, providing information about itself to the OpenID Provider, and obtaining information needed to use it, including the OAuth 2.0 Client ID for this Relying Party.

This document is available at: https://openid.net/specs/openid-connect-registration-1_0.html.

C.2.3 OpenID Connect Discovery

OpenID Connect 1.0 is a simple identity layer on top of the OAuth 2.0 protocol. It enables Clients to verify the identity of the End-User based on the authentication performed by an Authorization Server, as well as to obtain basic profile information about the End-User in an interoperable and REST-like manner. This specification defines a mechanism for an OpenID Connect Relying Party to discover the End-User's OpenID Provider and obtain information needed to interact with it, including its OAuth 2.0 endpoint locations.

This document is available at: https://openid.net/specs/openid-connect-discovery-1_0.html.

C.2.4 OAuth 2.0 Form Post Response Mode

This specification defines the Form Post Response Mode. In this mode, Authorization Response parameters are encoded as HTML form values that are auto-submitted in the User Agent, and thus are transmitted via the HTTP POST method to the Client, with the result parameters being encoded in the body using the application/x-www-form-urlencoded format [OAUTH2-FPRM].

This document is available at: http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html.

D. Revision History

This section is non-normative.

D.1 Version History

Version No. Release Date Comments
1EdTech Final Release 1.0 15th May 2019 The first formal Final Release of this document.
1EdTech Final Release 1.1 19th July 2021 The second formal Final Release of this document.

D.2 Changes in this Version

The changes made for this Final Release 1.1 document are:

  • Recommendations for migration from version 1.0 to 1.1 of the Security Framework by the different 1EdTech specifications have been added to Section 1.
  • Details for the support of Access Token Revocation under OAuth 2 Client Credentials, as per [RFC7009], has been included Section 4.1.
  • Details for the support of Access Token Refresh under OAuth 2 Authorization Code Grant, as per [RFC7009], has been included Section 4.2.
  • Details for the support of Access Token Revocation under OAuth 2 Authorization Code Grant, as per [RFC7009], has been included Section 4.2.
  • Details for the support of Dynamic Client Registration in the context of OAuth 2 using IETF RFC 7591 has been included in Section 4.3.
  • Details for the support of Dynamic Client Registration in the context of Open ID Connect has been included in Section 5.5.
  • Inclusion of an approved list of JWT signing algorithms i.e. the set of algorithms that SHOULD be supported and MUST be used with JWT signing. This information is added to the Best Practices section.
  • A best practice for compensating for clock skew has been added in the Best Practices.
  • A new Appendix has been added to provide a detailed example of how OpenAPI 3.0 (JSON) files are used as a Service Discovery Document.
  • A new Appendix has been added under which all of the changes required to the base specifications used by this Security Framework are collated.
  • Clarification on the requirement for the use of a HTTP POST request for obtaining access tokens has been added.
  • Clarification on how to pass the scope and other parameters in the request body when requesting an access token has been added.
  • The scope parameter has been added as a REQUIRED value in the redirect message within the Authorization Code Grant exchange.
  • Clarification on the passing of single values in arrays in the JSON Web Tokens has been added.
  • The overview on the usage of PKCE has been corrected.

E. References

E.1 Normative references

[ISO29115]
Information technology - Security techniques - Entity authentication assurance framework. URL: https://www.iso.org/standard/45138.html
[ITU-X1252]
X.1252: Baseline identity management terms and definitions. 2010. URL: https://www.itu.int/rec/T-REC-X.1252-201004-I
[JSONWT-BP]
JSON Web Token Best Current Practices (draft-ietf-oauth-jwt-bcp-04). IETF. November 08, 2019. Best Current Practice. URL: https://datatracker.ietf.org/doc/draft-ietf-oauth-jwt-bcp/
[LTI-13]
1EdTech Learning Tools Interoperability® Core Specification v1.3. C. Vervoort; N. Mills. 1EdTech Consortium. April 2019. 1EdTech Final Release. URL: https://www.imsglobal.org/spec/lti/v1p3/
[OAS3P0]
OpenAPI Specification 3.0. OpenAPI Initiative (Linux Foundation). July, 2017. URL: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.0.md
[OAUTH2-FPRM]
OAuth 2.0 Form Post Response Mode. OpenID Foundation. April 27, 2015. URL: http://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html
[OAUTH2-RESP]
OAuth 2.0 Multiple Response Type Encoding Practices. OpenID Foundation. February, 2014. URL: https://openid.net/specs/oauth-v2-multiple-response-types-1_0.html
[OAUTH2-SBP]
OAuth 2.0 Security Best Current Practice (draft-ietf-oauth-security-topics-11). IETF. December 28, 2019. Best Current Practice. URL: https://datatracker.ietf.org/doc/draft-ietf-oauth-security-topics/
[OPENID-CCORE]
OpenID Connect Core 1.0. OpenID Foundation. Nov 8 2014. URL: http://openid.net/specs/openid-connect-core-1_0.html
[OPENID-DCR]
OpenID Connect Dynamic Client Registration 1.0. OpenID Foundation. Nov 8 2014. URL: https://openid.net/specs/openid-connect-registration-1_0.html
[OPENID-DIS]
OpenID Connect Discovery 1.0. OpenID Foundation. Nov 8 2014. URL: https://openid.net/specs/openid-connect-discovery-1_0.html
[RFC2026]
The Internet Standards Process -- Revision 3. S. Bradner. IETF. October 1996. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2026
[RFC2068]
Hypertext Transfer Protocol -- HTTP/1.1. R. Fielding; J. Gettys; J. Mogul; H. Frystyk; T. Berners-Lee. IETF. January 1997. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc2068
[RFC2069]
An Extension to HTTP : Digest Access Authentication. J. Franks; P. Hallam-Baker; J. Hostetler; P. Leach; A. Luotonen; E. Sink; L. Stewart. IETF. January 1997. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc2069
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC2616]
Hypertext Transfer Protocol -- HTTP/1.1. R. Fielding; J. Gettys; J. Mogul; H. Frystyk; L. Masinter; P. Leach; T. Berners-Lee. IETF. June 1999. Draft Standard. URL: https://datatracker.ietf.org/doc/html/rfc2616
[RFC2617]
HTTP Authentication: Basic and Digest Access Authentication. J. Franks; P. Hallam-Baker; J. Hostetler; S. Lawrence; P. Leach; A. Luotonen; L. Stewart. IETF. June 1999. Draft Standard. URL: https://datatracker.ietf.org/doc/html/rfc2617
[RFC2828]
Internet Security Glossary. R. Shirey. IETF. May 2000. Informational. URL: https://datatracker.ietf.org/doc/html/rfc2828
[RFC3339]
Date and Time on the Internet: Timestamps. G. Klyne; C. Newman. IETF. July 2002. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc3339
[RFC3986]
Uniform Resource Identifier (URI): Generic Syntax. T. Berners-Lee; R. Fielding; L. Masinter. IETF. January 2005. Internet Standard. URL: https://datatracker.ietf.org/doc/html/rfc3986
[RFC4949]
Internet Security Glossary, Version 2. R. Shirey. IETF. August 2007. Informational. URL: https://datatracker.ietf.org/doc/html/rfc4949
[RFC5246]
The Transport Layer Security (TLS) Protocol Version 1.2. T. Dierks; E. Rescorla. IETF. August 2008. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc5246
[RFC5646]
Tags for Identifying Languages. A. Phillips, Ed.; M. Davis, Ed.. IETF. September 2009. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc5646
[RFC5849]
The OAuth 1.0 Protocol. E. Hammer-Lahav, Ed.. IETF. April 2010. Informational. URL: https://datatracker.ietf.org/doc/html/rfc5849
[RFC6749]
The OAuth 2.0 Authorization Framework. D. Hardt, Ed.. IETF. October 2012. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc6749
[RFC6750]
The OAuth 2.0 Authorization Framework: Bearer Token Usage. M. Jones; D. Hardt. IETF. October 2012. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc6750
[RFC6819]
OAuth 2.0 Threat Model and Security Considerations. T. Lodderstedt, Ed.; M. McGloin; P. Hunt. IETF. January 2013. Informational. URL: https://datatracker.ietf.org/doc/html/rfc6819
[RFC7009]
OAuth 2.0 Token Revocation. T. Lodderstedt, Ed.; S. Dronia; M. Scurtescu. IETF. August 2013. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7009
[RFC7515]
JSON Web Signature (JWS). M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7515
[RFC7517]
JSON Web Key (JWK). M. Jones. IETF. May 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7517
[RFC7518]
JSON Web Algorithms (JWA). M. Jones. IETF. May 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7518
[RFC7519]
JSON Web Token (JWT). M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7519
[RFC7523]
JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication and Authorization Grants. M. Jones; B. Campbell; C. Mortimore. IETF. May 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7523
[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://datatracker.ietf.org/doc/html/rfc7591
[RFC7592]
OAuth 2.0 Dynamic Client Registration Management Protocol. J. Richer, Ed.; M. Jones; J. Bradley; M. Machulak. IETF. July 2015. Experimental. URL: https://datatracker.ietf.org/doc/html/rfc7592
[RFC7636]
Proof Key for Code Exchange by OAuth Public Clients. N. Sakimura, Ed.; J. Bradley; N. Agarwal. IETF. September 2015. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7636
[RFC7952]
Defining and Using Metadata with YANG. L. Lhotka. IETF. August 2016. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc7952
[RFC8446]
The Transport Layer Security (TLS) Protocol Version 1.3. E. Rescorla. IETF. August 2018. Proposed Standard. URL: https://datatracker.ietf.org/doc/html/rfc8446
[WebMessaging]
HTML5 Web Messaging. W3C. January 28, 2021. W3C Recommendation. URL: https://www.w3.org/TR/webmessaging/

F. List of Contributors

The following individuals contributed to the development of this document:

Name Organization Role
Andrew CunninghamGoogle
Eric GalisCengageSecurity Committee
Paul GrayLearning Objects
Viktor HaagD2L
Karen HartmanBlackboardSecurity Committee
Dereck Haskins1EdTech
Martin LenordTurnitin
Mark Leuba1EdTech
Karl LloydInstructure
John McGettrickTurnitin
Mark McKell1EdTechEditor
Alex Medcalf-BellTurnitin
Nathan MillsInstructure
Bracken Mosbacker1EdTech
Padraig O'hiceadhaHMH
Burton PerkinsSavvasSecurity Committee
Marc PhillipsInstructure
Eric PrestonBlackboard
Coumara RadjaCisco SystemsSecurity Committee
James Rissler1EdTech
Charles SeveranceUniversity of Michigan
Sriram Seshadri CleverSecurity Committee
Lior ShorshiMcGraw-Hill Education
Colin Smythe1EdTechEditor
Uppili SrinivasanOracleSecurity Committee
James TseGoogle
Claude VervoortCengageEditor
Jim WalkoskiD2L

1EdTech Consortium, Inc. ("1EdTech") is publishing the information contained in this document ("Specification") for purposes of scientific, experimental, and scholarly collaboration only.

1EdTech makes no warranty or representation regarding the accuracy or completeness of the Specification.

This material is provided on an "As Is" and "As Available" basis.

The Specification is at all times subject to change and revision without notice.

It is your sole responsibility to evaluate the usefulness, accuracy, and completeness of the Specification as it relates to you.

1EdTech would appreciate receiving your comments and suggestions.

Please contact 1EdTech through our website at http://www.imsglobal.org.

Please refer to Document Name: 1EdTech Security Framework 1.1

Date: July 19th, 2021