Configuring LTI Advantage Tools

For versions of LTI previous to LTI 1.3, please refer to the older documentation

For a successful launch to occur, LTI Advantage Tools require configuration on both Canvas and inside the tool:

But first, the importance of each configuration setting can only be understood with a basic understanding of how an LTI launch occurs.

Overview of an LTI Launch

The IMS Security Framework uses an Open ID Connect (OIDC) third-party flow. You'll want to read these specifications in detail, but the following is a Canvas-specific summary:

Step 1: Login Initiation

Canvas initiates a login request to the oidc_initiation_url that is configured on the LTI developer key. This requests contains an issuer identifier (iss) to recognize Canvas is launching the tool. As the issuer, Instructure-hosted Canvas instances all use the following, regardless of the specific account domain(s) that the tool was launched from:

The request also includes a login_hint that is passed in the next step. Last, the request include the target_link_uri that has been configured on the Developer key; this is later used by the tool as a recommended final redirect.

Step 2: Authentication Request

To complete authentication, tools are expected to send back an authentication request to an "OIDC Authorization end-point". This can be a GET or POST, however, this request needs to be a redirect in the user’s browser and not made server to server as we need to validate the current user's session data. For cloud-hosted Canvas, regardless of the domain used by the client, the endpoint is always:

Among the required variables the request should include:

Step 3: Authentication Response (LTI Launch)

Canvas will use the client_id to lookup which developer key to use and then check the redirect_uri that was sent in the previous step and ensure that there is a exact-matching redirect_uri on the developer key. Canvas then sends its authentication response to the redirect_uri that the tool provided in Step 2. The request will include an id_token which is a signed JWT containing the LTI payload (user identifiers, course contextual data, custom data, etc.). Tools must validate the request is actually coming from Canvas using Canvas' public JWKs.

Step 4: Resource Display

The tool then validates the state parameter matches the one sent in Step 2 and redirects the User Agent to the target_link_uri that was sent in Step 1 (or some other location of its choice) to display the final resource. This redirect occurs in an iframe unless the tool is configured otherwise.

Launching without Cookies

Safari blocking cookies inside 3rd-party iframes made it necessary to create a workaround for storing the state property between the login and launch requests, to prevent MITM attacks. The (almost public final) LTI Platform Storage spec provides a way for tools that are launching in Safari or another situation where cookies can't get set to still store data across requests in a secure fashion. Tools can send window.postMessages to Canvas asking it to store and retrieve arbitrary data, which acts as a cookie-like proxy.

More details about this workflow will be provided once the Platform Storage spec is finalized and released to the public. Tool developers who work with the LTI working group most likely have access to these private docs, which details the postMessages used and the cookie-less launch flow. Tool developers who don't have access to these docs can request some implementation help via the partner team or the LTI working group, though a brief usage overview is included below:

In Step 2, instead of storing the state parameter in a cookie, the tool should store it in Canvas's LTI Platform Storage using the org.imsglobal.lti.put_data postMessage. It's recommended that the key include the value (eg key: "state-1234", value: "1234) to avoid any collisions during multiple launches, and to make recovering the value easy.

In Step 4, instead of comparing the state parameter to the stored value in the cookie, the tool should retrieve it using the org.imsglobal.lti.get_data postMessage. Since this comparison has to happen in Javascript instead of on the server, the tool should render something, then check these values. If the values don't match, the tool can then log the user out or render an error.

Note that Canvas supports most of the spec, including all message types, but does not currently support using the OIDC Auth URI as the target origin. Tools that want to use these postMessages to set and get data for launches or for other uses must currently direct all messages to the parent Canvas window, using the * wildcard origin.

Configuring Canvas in the Tool

Tools will need to be aware of some Canvas-specific settings in order to accept a launch from Canvas and use the LTI Advantage Services:

Configuring the Tool in Canvas

With LTI Advantage, Canvas moved to using Developer Keys to store tool configuration information. After a developer key is created and enabled, tools can be deployed to accounts/sub-accounts or courses.

Developer Keys allow tools to set the required parameters to complete the OpenID Connect Launch Flow, leverage LTI Advantage Services, and configure other important settings.

With guidance from the tool developer, developer keys settings can be manually entered by Account Admins. Tools providers can also supply Account Admins with a JSON configuration or configuration URL containing the settings the tool provider has verified to work.

In the manual case, since many of the extensions listed here require more than a few lines of configuration, there is not currently an interface for every extension to be manually configured. Instead, we encourage tool providers to expose a set of URL endpoints that return working configuration options for their tool services.

If providing a URL configuration endpoint is not an option, you can also provide your users with raw JSON that they can paste in for configuration.

Anatomy of a JSON configuration

In this section, an example JSON configuration is shown followed by a table describing the relevance of each field.

NOTE: Certain placement-specific settings may not be described here. Some examples of JSON configuration snippets and placement-specific settings are also found in the placements sub-menu in the left-navigation of this documentation.

{
   "title":"The Best Tool",
   "description":"1.3 Test Tool used for documentation purposes.",
   "oidc_initiation_url":"https://your.oidc_initiation_url",
   "target_link_uri":"https://your.target_link_uri",
   "scopes":[
       "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem",
       "https://purl.imsglobal.org/spec/lti-ags/scope/result.readonly"
    ],
   "extensions":[
      {
         "domain":"thebesttool.com",
         "tool_id":"the-best-tool",
         "platform":"canvas.instructure.com",
         "privacy_level":"public",
         "settings":{
            "text":"Launch The Best Tool",
            "icon_url":"https://some.icon.url/tool-level.png",
            "selection_height": 800,
            "selection_width": 800,
            "placements":[
               {
                  "text":"User Navigation Placement",
                  "icon_url":"https://some.icon.url/my_dashboard.png",
                  "placement":"user_navigation",
                  "message_type":"LtiResourceLinkRequest",
                  "target_link_uri":"https://your.target_link_uri/my_dashboard",
                  "canvas_icon_class":"icon-lti",
                  "custom_fields":{
                     "foo":"$Canvas.user.id"
                   }
               },
               {
                  "text":"Editor Button Placement",
                  "icon_url":"https://some.icon.url/editor_tool.png",
                  "placement":"editor_button",
                  "message_type":"LtiDeepLinkingRequest",
                  "target_link_uri":"https://your.target_link_uri/content_selector",
                  "selection_height": 500,
                  "selection_width": 500
               }
            ]
         }
      }
   ],
   "public_jwk":{
      "kty":"RSA",
      "alg":"RS256",
      "e":"AQAB",
      "kid":"8f796169-0ac4-48a3-a202-fa4f3d814fcd",
      "n":"nZD7QWmIwj-3N_RZ1qJjX6CdibU87y2l02yMay4KunambalP9g0fU9yZLwLX9WYJINcXZDUf6QeZ-SSbblET-h8Q4OvfSQ7iuu0WqcvBGy8M0qoZ7I-NiChw8dyybMJHgpiP_AyxpCQnp3bQ6829kb3fopbb4cAkOilwVRBYPhRLboXma0cwcllJHPLvMp1oGa7Ad8osmmJhXhM9qdFFASg_OCQdPnYVzp8gOFeOGwlXfSFEgt5vgeU25E-ycUOREcnP7BnMUk7wpwYqlE537LWGOV5z_1Dqcqc9LmN-z4HmNV7b23QZW4_mzKIOY4IqjmnUGgLU9ycFj5YGDCts7Q",
      "use":"sig"
   },
   "custom_fields":{
      "bar":"$Canvas.user.sisid"
   }

}
Parameter Type Description
title Required string

The default name of the tool in the app index. This value is also displayed if no "text" field is provided within extension settings or placements.

description Required string

A description of the tool

oidc_initiation_url Required string

The login initiation url that Canvas should redirect the User Agent to.

target_link_uri Required string

The target_link_uri that Canvas should pass in the to the login initiation endpoint. This allows tools to determine which redirect_uri to pass Canvas in the authorization redirect request and should be verified during the final launch. This can be set at the tool-level, or within the "placements" JSON object for placement-specific target_link_uri's

scopes string array

The comma separated list of scopes to be allowed when using the client_credentials grant to access LTI services.

Allowed values: "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-nrps/scope/contextmembership.readonly", "https://purl.imsglobal.org/spec/lti-ags/scope/lineitem.readonly", "https://canvas.instructure.com/lti/public_jwk/scope/update"

extensions JSON object

The set of Canvas extensions, including placements, that the tool should use

domain string

The domain Canvas should use to match clicked LTI links against. This is recommended if deep linking is used

.
tool_id string

Allows tools to set a unique identifier for the tool.

.
platform string

The LMS platform that the extensions belong to. This should always be set to "canvas.instructure.com" for cloud-hosted Canvas

privacy_level Required string

What level of user information to send to the external tool.

Allowed values: anonymous, public

settings JSON object

The set of platform-specific settings to be used.

icon_url string

The url of the icon to show for this tool. Can be set within the "settings" object for tool-level icons, or in the "placement" object for placement-specific icons. NOTE: Not all placements display an icon.

selection_height string

The display height of the iframe. This may be ignored or overridden for some LTI placements due to other UI requirements set by Canvas. Tools are advised to experiment with this setting to see what makes the most sense for their application.

selection_width string

The display width of the iframe. This may be ignored or overridden for some LTI placements due to other UI requirements set by Canvas. Tools are advised to experiment with this setting to see what makes the most sense for their application.

text string

The default text to show for this tool. Can be set within "settings" for the tool-level display text, or within "placements" object for placement-specific display text.

enabled boolean

Optional, defaults to `true`. Set within the "placements" object to to determine if the placement is enabled.

message_type string

The IMS message type to be sent in the launch. This is set at the placement level. Not all placements support both message_types.

Allowed values: "LtiResourceLinkRequest", "LtiDeepLinkingRequest"

public_jwk required, see notes JSON object

Required if public_jwk_url is omitted. The tools public key to be used during the client_credentials grant for accessing LTI Advantage services.

public_jwk_url required, see notes string

Required if public_jwk is omitted. The tools public key uri to be used during the client_credentials grant for accessing LTI Advantage services.

custom_fields JSON object

Custom fields that will be sent to the tool consumer; can be set at the tool-level or within the "placement" JSON object for placement-specific custom fields.