Sakai 3 Basic LTI… Now with more policies!

In an upcoming screencast, I will demonstrate a new Sakai 3 widget that hides all of the complexities of LTI settings from the end user. In the previous demonstration [1] you were able to see individual Sakai 2 tools living side-by-side with Sakai 3 widgets. You also saw a “sleight of hand” where I tried to paste in a 1) LTI URL, 2) LTI key, and 3) LTI shared secret without you noticing. While this made for decent “demo-ware”, it was an unreasonable set of expectations for a user who say simply wants to place a Sakai 2 Assignments tool onto a Sakai 3 page. My goal was to allow users to be able to place a Sakai 2 tool onto the page without having to know any settings.

To reach this next level of simplification, the required LTI settings would need to be supplied via administrative policies. Luckily, when I started developing the LTI service in Sakai 3, I anticipated such a need and built in some preliminary support for policies. Let’s start by taking a look at a policy, sakai.assignments.grades:

    "ltiKeys": {

All of the Basic LTI widget settings can be configured via such a policy. There are two aspects to each setting, 1) the setting itself and 2) a lock. The interaction between the two works as follows:

  1. If no setting is configured, the Basic LTI widget will not be affected in any way.
  2. If a setting is supplied (i.e. with no lock) it will become a default value for the setting in the widget.
  3. If both the setting and the corresponding lock are set, then it becomes a policy which the end user cannot change.

Hopefully this is fairly straightforward. However, we have not talked about the key to a policy itself. That is to ask, what causes an associated policy to be read and applied during the launch of the Basic LTI widget? It is another setting on the widget itself: lti_virtual_tool_id. For example, setting lti_virtual_tool_id to a value of sakai.assignments.grades would cause the policy named /var/basiclti/sakai.assignments.grades to be applied. This will allow system implementers to create many virtual tools and policies for end users, either because they want to simplify their lives with some good default values, or they need to lock some of the settings down so that end users cannot modify them. Now before you get too excited, the bad news is that while all of this logic exists and has been tested in the backend service itself, it has not been added to the Basic LTI widget yet. You will be able to see these policies in action in an upcoming blog posting where I will demonstrate a new widget called “Sakai 2 Tools”. This new widget essentially has no settings as relies completely on the new administrative policies.

While we are on the subject of policies, there is another new feature in the Basic LTI service worth mentioning. This is a little abstract, but essentially LTI has a property context_id which has meaning similar to what Sakai might call a siteId. The Sakai 3 LTI service now has the ability to manually specify the context_id if needed. This will be important to the Sakai 2/3 Hybrid integration as we will want Sakai 3 to pass the siteId of the corresponding Sakai 2 site as the context_id. Let me explain in more detail:

  1. The Sakai 2 LTI provider normally operates in the following provisioning manner:
    1. If the user does not exist, create it.
    2. If the site (i.e. context_id) does not exist, create it.
    3. If the tool placement does not exist, create it.
  2. This is all well and good if you are integrating some untrusted third party system where you want all of the LTI stuff to be completely separate from your local stuff.
  3. But if you are integrating with something closer to home (i.e. more trusted), then you probably don’t want all of this provisioning occurring.
  4. For a given LTI key, the Sakai 2 LTI provider can be placed into a trusted mode where it will not perform any account, site, or tool provisioning.

It is this trusted mode of the Sakai 2 LTI provider that we are targeting with the ability to manually specify the LTI context_id in Sakai 3. To invoke this new capability, simply set the property lti_context_id on the Sakai 3 site node to the siteId of the Sakai 2 site. As you can see from the DefaultContextIdResolver, the value of lti_context_id will be used if it exists, otherwise, the fully path to the site node will be used as the context_id.

  public String resolveContextId(final Node node) throws RepositoryException {
    LOG.debug("resolveContextId(Node {})", node);
    if (node == null) {
      throw new IllegalArgumentException("Node cannot be null");

    String contextId = null;
    if (node.hasProperty(key)) {
      // we have a special context_id we can use
      contextId = node.getProperty(key).getString();
    } else {
      // just use the path
      contextId = node.getPath();
    return contextId;

Until next time… L


Leave a comment

Filed under Sakai, Technology

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s