doc/lti/16_privacy_level.md
tl;dr A Canvas-specific extension to the LTI spec to support anonymous launches, plus some extras
anonymous - send no user-identifying claims
Private in the LTI Developer Key UIname_only - like anonymous, except send along only the user's nameemail_only - like anonymous, except send along the user's emailpublic - send all user-identifying claimssent if privacy_level is email_only OR public:
lis_person_contact_email_primarysent if privacy_level is name_only OR public:
lis_person_name_givenlis_person_name_familylis_person_name_fullsent if privacy_level is public:
user_imagecustom_canvas_user_idlis_person_sourcedidcustom_canvas_user_login_idcustom_canvas_course_id (for Course context)custom_canvas_workflow_state (for Course context)lis_course_offering_sourcedid (for Course context)custom_canvas_account_id (for Account or User context)custom_canvas_account_sis_id (for Account or User context)custom_canvas_api_domainrole_scope_mentor(none of these fields are sent if privacy_level is anonymous)
sent if privacy_level is email_only OR public:
emailsent if privacy_level is name_only OR public:
namegiven_namefamily_namehttps://purl.imsglobal.org/spec/lti/claim/lis
person_sourcedidcourse_offering_sourcedidsent if privacy_level is public:
picturerole_scope_mentor(none of these fields are sent if privacy_level is anonymous)
(specifically for the Member definition)
sent if privacy_level is email_only OR public:
emailsent if privacy_level is name_only OR public:
namegiven_namefamily_namelis_person_sourcedidsent if privacy_level is public:
picture(none of these fields are sent if privacy_level is anonymous)
app/controllers/external_tools_controller.rbdoc/api/lti_dev_key_config.mdThe privacy level is stored on the ContextExternalTool in its workflow_state attribute, which was a little misguided since that also denotes whether the tool is disabled or deleted. That is a (relatively) easy thing to remedy by separating into its own column.
The ContextExternalTool has boolean-returning methods for each of the possible values: include_email?, include_name?, and public?. These methods are referenced in a few different places:
gems/lti_outbound/lib/lti_outbound/tool_launch.rb - LTI 1.1 launches (technically references the LtiTool model, but that is populated by the ContextExternalTool)lib/lti/messages/jwt_message.rb - LTI 1.3 launchesapp/serializers/lti/ims/names_and_roles_serializer.rb - NRPS definitionsThe tool is created using the ExternalTool API, and the privacy_level is passed as a parameter and set directly on the tool.
The tool is created using the ExternalTool API, and the CC::Importer::BLTIConverter transforms the provided config_xml to tool attributes. The privacy_level is taken from the extensions property of the XML as shown here.
The user provides a JSON config in the Developer Keys UI, and saves the key. The tool is registered using a DeveloperKey and Lti::ToolConfiguration models. The privacy level is taken from the extensions property of the JSON tool configuration and stored in the Lti::ToolConfiguration's privacy_level column, and in its settings hash as well. During tool deployment (installation into a context), the settings hash is copied to the tool and the tool's workflow_state is set using the privacy_level.
The user fills out the form in the Developer Keys UI, including choosing between Public (public), and Private (anonymous) privacy levels. The privacy level is saved into the extensions property of the form's JSON state, and then is registered using the same flow as above.