Daily Archives: June 14, 2013

Receiving Grades IMS LTI Outcomes: Signed sourcedids

This is a design for an approach to securely accept grades from an external tool and put those grades in the grade book. Please review this design for security and feasibility.

Overview of the Structure of IMS Outcomes

When you look at the IMS Learning Tools Interoperability 1.1 (LTI) Launch, there is a field called the lis_result_sourcedid. If the administrator and instructor decide that a particular resource_link_id is to send grades to the grade book, they must create the column in the grade book and indicate which grade book column to accumulate grades for the particular resource.

The lis_result_sourcedid must contain enough information to uniquely identify the resource_link_id, course, and particular row and column to store a grade for the user. The value will be different for each tool launch from a different user. When the external tool wants to set a grade for a user, it must present the lis_result_sourcedid for that user_id/resource_link_id combination. This value is completely opaque to the tool – the tool is not supposed to be able to parse or otherwise understand this string – the tool must simply receive the value, store it and then present it when attempting to set a a grade.

This gives the Tool Consumer a wide range of choices as to how it constructs the lis_result_sourcedid. This document describes the particular approach that I use and recommend to create this lis_result_sourcedid.

Data Model for Resource Link Level Grade Secrets

To support this feature, we will add the following data items in the LTI Resource Links. This value need not be visible to the Instructor and there is little value revealing the value to the Instructor or admin.

imslti.gradesecret=random UUID

The LTI code generates the secret internally once the instructor or admin has indicated that this resource_link_id is supposed to accept grades.

During Launch: Constructing the lis_result_sourcedid

The essential data needed in the lis_result_sourcedid is the resource_link_id and the userid. The key is to make sure that the lis_result_sourcedid cannot be tampered with while the tool in possession of the lis_result_sourcedid. The base string will be as follows:

gradesecret + ':::' + resource_link_id + ':::' + user_id

A SHA1 signature will be computed from that base string and the lis_result_sourcedid sent in the launch will be:

signature + ':::' + resource_link_id + ':::' + user_id

All the other information regarding the grade book comes from data stored in the content item associated with the resource_link_id so there is no need to replicate this information in the lis_result_sourcedid. These is little reason to otherwise encrypt the lis_result_sourcedid as it simply contains information the external tool already knows.

So the only protection needed is to insure the integrity of the resource_link_id/user_id using a simple message signature. Encrypting the lis_result_sourcedid further would obfuscate the information for no particular increase in security but it can be done if the TC wants to do so.

The resulting lis_result_sourcedid will be sent with LTI launches for which the instructor has configured the tool to receive grades.

Use Case Walk Through

This section walks through the entire steps of the process in order.

Instructor or admin places the LTI resource link and configures with the url, secret, and key.
Instructor or admin uses the LTI config UI to indicate that the tool will be sending grades, and picks the grade book column to store results if necessary. This causes the imsti.gradebooksecret property to be set with a random UUID if it is not already set.

Student launches the tool in the consumer The launch includes the lis_result_sourcedid which is the resource_link_id and user_id and an integrity signature based on gradebooksecret.

The Tool Provider stores the lis_result_sourcedid for each user_id in its tables somewhere, remembering the oauth_consumer_key as well.

Student uses the tool and earns a grade, or perhaps the student uses the tool and the instructor goes into the tool and grades the student work and requests that grades be sent back to the TC.

Either as a side effect of the student completing the work, or the instructor pressing a “send-grades” button, the tool provider creates a Outcomes service request message including the lis_result_sourcedid and sign the overall message it using OAuth using the oauth_consumer_key which the Tool Consumer used to sign the launch request.

The overall message signature establishes that the TP indeed sent the message and that the message contents were not modified while in-transit.

The service message is sent to the designated service URL on the tool consumer.

(1) The TC parses the lis_result_sourcedid, producing a signature, resource_link_id and user_id.
(2) The TC looks up the content item using the resource_link_id
(3) It then pulls gradesecret from the content item and checks the lis_result_sourcedid signature
(4) It then looks up the oauth_consumer_key and secret from the content item (or from a system wide registry) and checks the OAuth signature of the message.
(5) The TC verifies that the user_id is a member of the context_id that contains the content item (resource_link_id).

If all of the above tests pass – we set the grade.

Advanced Concepts (Optional)

Since these secrets are system generated and not user entered, a TC can come up with a “rotation”policy to change the grade secret periodically for each resource_link_id. To do this we add two new data items to each resource link associated with a resource_link_id:

imslti.gradesecretdate=Date The gradesecret was set
imslti.oldgradesecret=The Immediate prior secret

Based on some time scale chosen by the TC administrator, the TC can go through and “expire secrets” that are older than some desired time period. The regeneration process can copy the current value for gradesecret to oldgradesecret and then generate a new gradesecret and update the gradesecretdate. The verification process above is updated to check both the gradesecret and oldgradesecret and accept either as valid.

The launch process simply uses the latest gradesecret when it signs the lis_result_sourcedid during a launch thus extending the expiry date on the lis_result_sourcedid.

If the TC system automatically regenerates all gradesecret values after 15 days, it will appear to the TP that signed lis_result_sourcedid values expire after a minimum of 15 and maximum of 30 days depending on the relative timing of the generation of the gradesecret and the generation of the lis_result_sourcedid.

A gradesecret and/or oldgradesecret can be manually altered, removed or regenerated at any time to “invalidate” all outstanding lis_result_sourcedid values.

Sample Source Code

This is implemented in the Sakai ServiceServlet here is the code below:

https://source.sakaiproject.org/svn/basiclti/trunk/basiclti-blis/src/java/org/sakaiproject/blti/ServiceServlet.java

Look for the doPostXml method and walk through it (patches welcome). There are libraries of code elsewhere in the source tree – but this is the starting point for Sakai’s outcome service code.

Conclusion

This document introduces the notion of a signed lis_result_sourcedid that allows very fine-grained authorization down to the individual user / resource_link_id if the TC so chooses. The approach includes provisions for grade secret revocation, and seamless grade secret expiry and rotation.

Comments welcome…

Original document written: Version: 3 – August 18, 2010