Ltix.LaunchClaims (Ltix v0.1.0)

Copy Markdown View Source

Structured representation of claims from an LTI launch JWT.

Standard OIDC and LTI claims are mapped to named fields, while any unrecognized claims are available in extensions. Access claims through context.claims after a successful launch:

{:ok, context} = Ltix.handle_callback(params, state)
context.claims.issuer          #=> "https://platform.example.com"
context.claims.target_link_uri #=> "https://tool.example.com/launch"
Role.instructor?(context.claims.roles)  #=> true

Fields

Identity

  • :issuer — platform identifier (matches iss in the JWT)
  • :subject — user identifier on the platform (matches sub)
  • :audience — tool's client_id (string or list of strings)
  • :nonce — replay prevention token
  • :authorized_partyazp claim, present when audience is a list
  • :expires_at — JWT expiration as a Unix timestamp
  • :issued_at — JWT issue time as a Unix timestamp

User profile

Profile fields depend on platform consent and privacy settings. Any may be nil.

  • :name — full display name
  • :given_name, :family_name, :middle_name — name parts
  • :email — email address
  • :picture — profile image URL
  • :locale — user's locale (e.g., "en")

LTI launch

  • :message_type — launch type (e.g., "LtiResourceLinkRequest", "LtiDeepLinkingRequest")
  • :version — LTI version (e.g., "1.3.0")
  • :deployment_id — identifies the specific tool installation
  • :target_link_uri — URL the tool should load
  • :roles — list of parsed Ltix.LaunchClaims.Role.t/0 structs
  • :unrecognized_roles — role URIs that could not be parsed
  • :role_scope_mentor — list of user IDs this user mentors
  • :custom — custom parameters set by the platform administrator

Nested claims

Advantage service endpoints

Present when the platform supports the corresponding service. Pass the parent %LaunchContext{} to the service's authenticate/2.

Extensions

  • :extensions — map of unrecognized claim keys to their raw values. Register custom parsers via the :parsers option in from_json/2 or application config (:ltix, Ltix.LaunchClaims, :claim_parsers).

Examples

iex> {:ok, claims} = Ltix.LaunchClaims.from_json(%{"iss" => "https://example.com", "sub" => "user-1"})
iex> claims.issuer
"https://example.com"

Summary

Functions

Parse a JWT body map into a %LaunchClaims{} struct.

Types

t()

@type t() :: %Ltix.LaunchClaims{
  ags_endpoint: Ltix.LaunchClaims.AgsEndpoint.t() | nil,
  audience: String.t() | [String.t()] | nil,
  authorized_party: String.t() | nil,
  context: Ltix.LaunchClaims.Context.t() | nil,
  custom: map() | nil,
  deep_linking_settings: Ltix.LaunchClaims.DeepLinkingSettings.t() | nil,
  deployment_id: String.t() | nil,
  email: String.t() | nil,
  expires_at: integer() | nil,
  extensions: %{optional(String.t()) => term()},
  family_name: String.t() | nil,
  given_name: String.t() | nil,
  issued_at: integer() | nil,
  issuer: String.t() | nil,
  launch_presentation: Ltix.LaunchClaims.LaunchPresentation.t() | nil,
  lis: Ltix.LaunchClaims.Lis.t() | nil,
  locale: String.t() | nil,
  memberships_endpoint: Ltix.LaunchClaims.MembershipsEndpoint.t() | nil,
  message_type: String.t() | nil,
  middle_name: String.t() | nil,
  name: String.t() | nil,
  nonce: String.t() | nil,
  picture: String.t() | nil,
  resource_link: Ltix.LaunchClaims.ResourceLink.t() | nil,
  role_scope_mentor: [String.t()] | nil,
  roles: [Ltix.LaunchClaims.Role.t()],
  subject: String.t() | nil,
  target_link_uri: String.t() | nil,
  tool_platform: Ltix.LaunchClaims.ToolPlatform.t() | nil,
  unrecognized_roles: [String.t()],
  version: String.t() | nil
}

Functions

from_json(json, opts \\ [])

@spec from_json(
  map(),
  keyword()
) :: {:ok, t()} | {:error, Exception.t()}

Parse a JWT body map into a %LaunchClaims{} struct.

Options

  • :parsers — Map of extension claim keys to parser functions. Each parser receives the raw value and must return {:ok, parsed} or {:error, reason}. Per-call parsers override application config.
  • :role_parsers — Map of role URI prefixes to parser functions for parsing the roles claim. Each parser receives a role URI and must return a {:ok, t:Ltix.LaunchClaims.Role.t/0} struct or :error. Per-call parsers override application config.

Examples

iex> {:ok, claims} = Ltix.LaunchClaims.from_json(%{
...>   "iss" => "https://platform.example.com",
...>   "https://purl.imsglobal.org/spec/lti/claim/message_type" => "LtiResourceLinkRequest"
...> })
iex> {claims.issuer, claims.message_type}
{"https://platform.example.com", "LtiResourceLinkRequest"}