Skip to content
Skip article header Engineering

LTI Advantage Integration

The platform half of an LTI Advantage integration, which the tool-side tutorials never cover: the identifiers a learning platform mints, the login it issues, the token it signs, the key set it publishes and the gradebook and roster endpoints it exposes. With the service table, the migration claim that keeps existing records attached and why the Complete certification level is required for platforms.

Updated 20 min read 66 views
Engineers reviewing an LTI Advantage integration launch from an LMS course page.
Skip key takeaways

This guide covers the platform side of an LTI Advantage integration, which public guidance mostly leaves to the tool side. A custom learning platform inherits the harder half: it mints the identifiers, signs the token, publishes the keys and hosts the service endpoints. The core specification, published by 1EdTech, the organization formerly named IMS Global Learning Consortium, defines that role in its LTI Core Specification 1.3: "A tool platform or, more simply, platform has traditionally been a Learning Management Systems (LMS), but it may be any kind of platform that needs to delegate bits of functionality out to a suite of tools".

In short: Your platform is an OpenID Provider that signs every launch, a key-set publisher, an authorization server for service calls and the owner of the gradebook a tool writes into. Three services make up LTI Advantage: Deep Linking, Assignment and Grade Services and Names and Role Provisioning Services, each advertised as a resolved URL inside the launch rather than discovered. Dynamic registration is an optional companion at Candidate Final status, outside that package. Certification sets the highest bar for platforms.

The platform role and the tool role

An LTI integration has two actors and the asymmetry between them is the whole story. Per the core specification, "Platforms in LTI acts as OpenID Providers and LTI Messages are OpenID tokens communicating the End-User's identity from the platform to the tool using the OpenID third-party initiated login flow." A tool consumes messages and calls services; a platform produces messages and, for the Advantage services, hosts them.

For the wider platform this layer sits inside, see our education software development guide.

Registrations and deployments

The migration guide gives the reason: "To better support this model, LTI 1.3 separates the registration of the tool (security and configuration) from its actual deployment." Registration is the security contract between one platform and one tool. Deployment is an instance of it inside a scope of contexts.

Registration typically happens once. In the words of the core specification, "In this deployment model, the tool is registered once; during registration, the security contract is established, keys are exchanged and a client_id is created by the platform." Deployment happens as often as an administrator wants: "When a user deploys a tool within their tool platform, the platform MUST generate an immutable deployment_id identifier to identify the integration. A platform MUST generate a unique deployment_id for each tool it integrates with."

Below the deployment sit contexts and links: a context is typically a course, a link one placement of the tool inside it. Per the core specification, "A platform MUST distinguish between each of these LTI links by assigning a resource_link_id to an LTI Link", and links in one context share a context_id while each carries its own resource_link_id.

Dynamic registration automates the exchange an administrator would otherwise perform by hand, and it keeps a human in the loop, because the dynamic registration specification separates configuration from activation: "The platform must immediately grant or deny the registration. A successful registration means the tool is properly configured, but it is not activated yet." An administrator then reviews, alters, rejects or activates it. Note the status, which is easy to miss: this is a Candidate Final optional companion service rather than a member of LTI Advantage.

The login the platform issues

A launch is an OpenID Connect flow the platform starts and the tool answers. The 1EdTech Security Framework requires that "each message request MUST be treated as a 3rd party initiated login, as defined in OpenID Connect: Initiating Login from a Third Party", which is what closes the login CSRF hole. That document covers every 1EdTech service, so it says Consumer where LTI says tool.

Two checks precede signing, and the same Security Framework states both. Silent authentication is required: "Since the message launch is meant to be sent from a platform where the user is already logged in. If the user has no session, a platform must just fail the flow rather than ask the user to log in." The return target is validated before the token exists: "Once the platform has validated the redirect_uri as a valid end point for the client_id" and matched the signed-in session against the login hint, it constructs the identity token.

That token is a signed JWT carrying the LTI claims: message_type with the value LtiResourceLinkRequest, plus version, deployment_id, target_link_uri, resource_link and roles, alongside the OpenID Connect iss, aud, sub, exp, iat and nonce. The first trap is a version string: the specification's own version is 1.3, while the string the version claim carries is 1.3.0.

Trap two is the target link URI, which must appear as a claim repeating the value sent at initiation. The core specification tells tools to prefer the claim: "A Tool should rely on this claim rather than the initial target_link_uri to do the final redirection, since the login initiation request is unsigned." Leave it out and conforming tools break at the final redirect.

Signing keys, key sets and rotation

A security key and printed key rotation schedule for signing key management.

A platform that signs with a key set must publish it. The Security Framework states it: "When systems use Key Sets, they MUST provide a URL to the key set (the system responsible for supplying this URL must be identified in the corresponding 1EdTech service specification)." Host it as a stable, cacheable, unauthenticated endpoint.

Identifiers are mandatory even in the trivial case. Per the same framework, "The supplier of the key set URL MUST use the kid parameter to identify the keys. Even when there is only one key in a key-set a kid MUST be supplied." Rotation then has one safe shape: "When the Issuer rotates its public key, the Issuer MUST add it to the JSON Key Set under a new kid". Publish both keys, start signing with the new one after a propagation window and retire the old one afterwards, and no tool notices.

Algorithms have a floor rather than a menu: RSA keys must use SHA-256 as a minimum, and the framework notes that other algorithms limit interoperability.

The security model and the service token

Two launch parameters do two jobs and neither substitutes for the other. In Security Framework terms, state is an "Opaque value for the platform to maintain state between the request and callback and provide Cross-Site Request Forgery (CSRF) mitigation." while nonce is a "String value used to associate a Client session with an ID Token, and to mitigate replay attacks. The value is passed through unmodified from the Authentication Request to the ID Token." Copy the nonce through unmodified from the authentication request into the token and refuse a repeat; state belongs to the tool.

Service calls run on a different credential, and tools do not authenticate service calls with the launch token. Per the framework, "Consumers MUST use the OAuth 2.0 Client Credentials grant type." and a tool names the scopes it needs in the token request, so your platform runs a token endpoint that accepts a signed client assertion, typically valid for about five minutes, and returns a scoped access token.

Validating that assertion has one clause worth memorizing, because older material contradicts it. The core specification says: "When requesting an access token, the client assertion JWT iss and sub must both be the OAuth 2 client_id of the tool as issued by the learning platform during registration."

That sentence arrived through an erratum rather than the original text. Six errata have amended the core specification since publication, the most recent dated 1 July 2021, and they are listed on the specification's own errata page.

Lifetime constrains storage more than handlers. One hour is the recommended access-token validity, and there is no renewal path, since "Client-credentials based OAuth 2 does NOT permit the use of access token refreshing. Therefore, once an access token has expired, a new access token MUST be requested." according to the Security Framework.

What the platform exposes, service by service

No service endpoint in LTI is discovered. The core specification is categorical: "LTI does not rely on prior knowledge of service endpoints. Rather, the platform MUST include in each message applicable service endpoints as fully resolved URLs (not as URL templates)." Your message builder composes absolute service URLs at launch time, per deployment and per context.

Columns one to four below come from the specifications named in each row. Column five is editorial and ours, because the LTI Advantage Conformance Certification Guide is normative but published by reference, so no reachable source states what a run checks per service. Scope strings and claim names appear in code font, attributed by title and never quoted, since they live in tables and JSON examples.

Service (sourced) Endpoint the platform exposes (sourced) Scope (sourced, by title) Key claims (sourced) Evidence to prepare (editorial, ours)
Core resource link launch OIDC authentication endpoint, the key set URL and the token endpoint none, a signed token rather than a service call message_type, version, deployment_id, target_link_uri, resource_link, roles A launch a tool validates end to end: signature checked against the key set, issuer matched, audience listing that tool's client_id and no audience the tool does not trust
Deep Linking 2.0 The return URL inside the deep linking settings claim, receiving the response as a form POST none, the response is a signed JWT deep_linking_settings with deep_link_return_url, then content_items on the response A response the platform accepts, a returned link whose URL becomes the later launch target, an empty selection treated as a cancellation
Line items (AGS 2.0) The line item container URL and, when the link has one, the line item URL lineitem for management and lineitem.readonly for read access The AGS endpoint claim carrying lineitems, lineitem and scope A line item created, read, updated and deleted at its own URL, a binding refused when the resource link belongs to another tool
Results (AGS 2.0) The line item URL with a results path appended, derived not advertised result.readonly The same claim; results are addressed per line item A read returning the current value for every enrolled member, absent results omitted or returned without a score, never zeroed
Scores (AGS 2.0) The line item URL with a scores path appended, likewise derived score The same claim; a score carries a timestamp, the score and maximum, the user, activityProgress and gradingProgress A posted score updating the cell, a partially graded score held back, a replayed post producing no second entry
Names and Role Provisioning Services 2.0 The context memberships URL carried in the names and role service claim contextmembership.readonly, read only The NRPS claim with the memberships URL and the service versions A roster read returning the minimum member shape, the role filter narrowing it, active assumed when status is absent, removals via a differences URL
Dynamic Registration 1.0, optional companion at Candidate Final The OpenID configuration URL and the registration endpoint it names registration and registration.readonly The response echoing the new client_id and the configuration as recorded A registration granted immediately but inactive until an administrator activates it, and a configuration echoed back narrower than requested

The engineering the specifications leave to you

Three problems sit outside every document cited here. They are ours, written as engineering practice rather than as requirements.

Key management in a multi-tenant platform comes first. One signing key for the whole installation fails badly, since a single compromise forces a rotation visible to every tool. Our default is a small pool of platform-level keys with per-tenant issuers, rotated with an overlap window measured in days.

Deployment-scoped authorization comes second, and it is where the security bugs live. A token is scoped by client and by scope string, neither of which says which course a call concerns, so authorization is re-derived per request: the line item URL names a context, the context belongs to a deployment, the deployment belongs to the registration the token was issued to, and any mismatch is a refusal. Build it as one checked path rather than a condition repeated in each handler.

Idempotent score ingestion comes third, because tools retry and networks duplicate, while a posted score carries a timestamp that lets you order writes without trusting arrival order. Our approach is a natural key over line item, user and timestamp, with a later timestamp winning and an equal one discarded, plus an append-only log of every accepted post.

Deep Linking and content selection

Deep linking is the flow where an instructor picks content inside the tool and the platform stores it as a link. Mechanically it starts like a launch, as an HTML form the browser auto-submits to a tool endpoint by POST, with a settings claim stating which item types this interaction accepts. Ownership of the interface is where platform teams push back, and the Deep Linking 2.0 specification is unambiguous: "The tool entirely controls the user experience for discovering and selecting content items within its body of available resources. The tool SHOULD verify the deep linking request message in the same way it would for a resource link launch request." Present that interface unrestyled in a frame or a window.

Return handling is a platform obligation with a named field: "When forming the deep linking request message, the platform includes a deep_link_return_url in the https://purl.imsglobal.org/spec/lti-dl/claim/deep_linking_settings claim. The tool MUST redirect the workflow to that URL once the user has completed the selection or creation portion of the overall flow." according to the Deep Linking specification. Scope that URL to the interaction that created it and expire it.

The response may be empty, and the specification defines both cases together: "A possibly empty JSON array of selected content items all appear composed within the https://purl.imsglobal.org/spec/lti-dl/claim/content_items claim. An empty array or the absence of this claim indicates there should be no item added as a result of this interaction." Treating an empty response as an error is non-conforming, and users produce it by closing the picker.

Five content item types are defined, a link, an LTI resource link, a file, an HTML fragment and an image, each with its own JSON schema. One carries a behavioral obligation for you. Per the Deep Linking specification, "If a platform receives a url then it MUST use this url as the target_link_uri in the LtiResourceLinkRequest payload."

Assignment and Grade Services

Grades are where the platform becomes a system of record, and advertising the service is conditional: per the Assignment and Grade Services 2.0 specification, the endpoint claim "MUST be included in LTI messages if any of the Assignment and Grade Services are accessible by the tool in the context of the LTI message." Its properties are written as a bullet list, and the one with real conditions attached is lineitem, defined as follows: "when an LTI message is launching a resource associated to one and only one lineitem, the claim must include the endpoint URL for accessing the associated line item; in all other cases, this property must be either blank or not included in the claim." A platform that always emits a line item URL has told the tool something untrue about the launch.

Binding a column to a placement carries a check that platform teams skip. Per the specification, "A line item MAY be attached to a resource link by including a 'resourceLinkId' in the payload. The resource link MUST exist in the context where the line item is created, and MUST be a link owned by the same tool." Without it, one tool can attach its gradebook column to another tool's placement inside a course both are installed in.

Direction of ownership is the concept most first implementations get backwards. A result is yours; a score is the tool's assertion about it. The specification defines the former exactly: "The Result is the current score within the Tool Consumer for the line item and user i.e. the value currently showing in the cell for that column and user in a typical tabular gradebook." Scores arrive by POST and your gradebook decides what they do to the cell, which makes ingestion a write path with policy in it. The grading progress field is the control signal: "gradingProgress MUST be used to indicate to the platform the status of the grading process, including allowing to inform when human intervention is needed." Only a fully graded value should reach the visible cell.

Names and Role Provisioning Services

Rosters are the third Advantage service. Its specification gives the purpose: "It is concerned with providing access to data about users’ roles within organizations, a course being an example of an organization. So a very common purpose for this service is to provide a roster (list of enrolments) for a course."

Minimal disclosure is a rule rather than a setting. Per the specification, "Any other member attributes will need an explicit consent from the Platform to be shared with the Tool. The Platform may delegate that consent to the actual member, therefore a Tool should never rely on additional member attributes to be present." Names and email addresses are released by policy, per tool and possibly per member, and the code that assembles a membership response is where that belongs.

Query semantics are small. A read is the only operation, carrying a scoped token and the membership container media type, a role parameter narrows the result and a limit parameter is advisory. Pagination travels in a link header, and the absence of a next link means the tool holds the whole roster.

Status carries a default that silently changes behavior. Memberships are active or inactive, and per the specification, "If the status is not specified then a status of Active must be assumed." Dropped enrollments need an explicit inactive status rather than an omission. Removals surface separately: "When present this will specify a differences URL which the service user may use to obtain a report of all the differences in the membership between the time the differences URL was created and the time the URL is used". That is a comparison between two points rather than a change log, so your implementation needs a snapshot to diff against.

Failure modes seen in practice

Five failures account for most of the platform-side bugs we meet. They are our observations rather than specification content, and each is cheap to test for.

A key set published without a key identifier breaks the first tool that keeps more than one key per issuer. A key replaced in place rather than added under a new identifier turns every in-flight validation into a signature failure, reported to you as a tool bug days later. A launch that omits the target link URI claim, or sends one that disagrees with the initiation request, breaks at the final redirect, the least diagnosable point in the flow. An empty deep linking response treated as an error turns a user closing the picker into a support ticket. And an authorization path that trusts the scope string alone lets one tool reach another tool's grades inside a course both are installed in, the failure that matters most and shows least.

Migrating from the older LTI generation

Platforms rarely start clean: an existing estate has 1.1 integrations built on shared keys and secrets, and courses full of links that already work. Those links survive, because the newer specifications avoided redefining what an LTI link is. What changes is the runtime beneath them, and the parameter map in the migration guide is implemented once: the version value becomes 1.3.0, the user identifier becomes the token subject, resource link and context parameters fold into structured claims, short role names give way to fully qualified role URIs and the outcomes service URL becomes the line item property of the AGS endpoint claim.

Identity continuity is the hard part and it has a dedicated claim. Per the migration guide, "This specification introduces the claim https://purl.imsglobal.org/spec/lti/claim/lti1p1 which allows a platform to pass to the tool a mapping of ids that have shifted with the transition to LTI 1.3, allowing the tool to associate existing records to new LTI 1.3 identifiers." It carries the old user, context, platform instance and resource link identifiers where they differ from the new ones. Two obligations attach and both are absolute: "If a platform supports this claim, it MUST include that claim in all messages sent to the tool, including resource links and deep linking messages." and "The migration data is immutable, the platform MUST NOT change the mapping once it has been advertised." Treat that map as an append-only table, because a tool that already merged records against it cannot un-merge them.

Certification as a process

Certification is not a badge bought at the end but the bar you build against, and the specifications point at a document rather than at themselves. The core specification names it as normative: "The LTI Advantage Conformance Certification Guide describes the procedures for testing Platforms and Tools against the LTI v1.3 and LTI Advantage services using the IMS certification test suite." More consequentially, that guide can be stricter than what you read: "The Conformance and Certification Guide for this specification may introduce greater normative constraints than those defined here for specific service or implementation categories."

What certification asserts is interoperability rather than quality: a set of tests verifying that the standard was implemented correctly. Testing runs through the current diagnostic and certification suite at build.1edtech.org, which is where the legacy validator URL now redirects.

Scope is the fact that should shape a platform roadmap. Per the LTI Advantage overview, "A product that completes certification testing for core LTI 1.3 and all three LTI Advantage services is recognized as LTI Advantage Complete" and, in the next sentence, "This type of certification is required for learning platforms; it is available but not required for tools." The tool-side bar is lower by design: "A tool that passes testing for LTI 1.3 and at least one LTI Advantage service is considered LTI Advantage certified." Partial service coverage is a viable tool strategy and not a viable platform one.

Certification also recurs. The certification page sets two standing conditions: "Products must be recertified annually. Active 1EdTech membership is required to maintain certification."

How Pharos Production helps

The platform side of LTI is a security surface, a service surface and a data model, and it has to be right before the first institution installs its first tool. Most of the work sits behind the launch, in the key lifecycle, the authorization path and the gradebook write path.

Our education software development practice covers exactly that layer: the OpenID Provider and the key set behind it, deployment-scoped authorization and the gradebook and roster endpoints a custom learning platform has to host. Tell us which Advantage services your tools expect and we will scope that work against the specifications.

Sources: 1EdTech specification pages on imsglobal.org (LTI Core Specification 1.3 and its errata, the Security Framework 1.0, Deep Linking 2.0, Assignment and Grade Services 2.0, Names and Role Provisioning Services 2.0, Dynamic Registration 1.0 and the LTI 1.3 Migration Guide); the LTI Advantage Overview; 1EdTech Consortium pages on 1edtech.org; the certification suite at build.1edtech.org; the LTI Advantage Conformance Certification Guide, cited by title. Read on 16 September 2026. Engineering guidance, not legal advice.

FAQ

Last updated:

Quick answers to common questions about custom software development, pricing, process and technology.

  • What is the difference between LTI 1.3 and LTI Advantage?

    LTI 1.3 is the core specification: the platform and tool roles, deployments, the signed launch and the claims it carries. LTI Advantage is the name of the package that adds three services on top of that core, namely Deep Linking, Assignment and Grade Services and Names and Role Provisioning Services.

    It is a package name rather than a version number, so a product implements core LTI 1.3 and then some or all of the three services. Dynamic registration is a separate optional service at Candidate Final status and sits outside the package.

  • When is adopting an existing certified platform the better call than implementing the platform role?

    This is our judgment rather than anything the specifications say. Implementing the platform role earns its cost when the learning experience is the product and the tool ecosystem is part of it, because the launch, the gradebook and the roster then sit on your own data model and your own identity system.

    Adopting an existing certified platform is the better call when interoperability is a checkbox on a roadmap that is really about something else, or when no team will own the key lifecycle for years. What decides it is the standing obligation rather than the first build.

  • Which LTI Advantage service should a platform ship first?

    Ours is a sequencing rule, not a requirement. Ship the service that carries the data your tools cannot work without, which on most learning platforms is Names and Role Provisioning, because a tool that cannot see a roster cannot place a user in a course context at all.

    Assignment and Grade Services comes next, since grades land in a system of record and the write path needs policy that takes time to get right. Deep Linking usually goes last, because content selection is a convenience an administrator can replace by pasting a URL.

  • What tolerances does a platform need on token timestamps and nonces?

    Two defaults we document on our own builds rather than specification requirements. Clocks on the two sides will disagree, so an issued-at or expiry check needs a small skew tolerance rather than exact agreement, and that tolerance belongs in configuration where it can be tightened per deployment instead of compiled into a handler.

    Nonce retention is the mirror image: a nonce has to stay in the store for at least as long as the token carrying it could still be presented, so the retention window is derived from the token expiry rather than chosen on its own.

  • Is dynamic registration required for LTI Advantage?

    No. It is an optional service at Candidate Final status, published separately from the three services that make up the package. What it buys you is operational: instead of an administrator copying identifiers and URLs between two admin screens, the platform opens the tool's initiate-registration endpoint, the tool reads your OpenID configuration and posts itself to your registration endpoint, and your platform returns a newly created client identifier.

    The registration is configured but inactive until an administrator reviews and activates it, which keeps a human in the approval path.

  • What usually breaks on a first LTI integration?

    From our own integrations, three causes account for most of it and none is exotic. The commonest is a mismatch between what was registered and what is being sent: a redirect target the platform never stored, an issuer string differing by a trailing character, a client identifier taken from the wrong environment.

    Second comes time: a token rejected as expired because the two systems disagree about the clock. The third is deployment state, where a registration exists but the deployment it names was never activated. All three surface as a generic authentication failure on the tool side.

I work with startup founders who need a dedicated software development team but don’t want to gamble on hiring, random outsourcing, or opaque delivery.
Most founders face the same problem sooner or later.
Early technical and team decisions lock the product into tech debt, slow delivery, missed milestones and constant re-hiring. By the time this becomes visible, fixing it is already expensive.

As a CTO and software architect, I help founders design, build and run dedicated development teams that work as a true extension of the startup. Not as a black-box vendor.

My focus is on complex products where mistakes are costly:

  • Web3 and blockchain platforms
  • FinTech and regulated products
  • High-load startup systems
  • MVP → scale transitions

We don’t do body-shopping.
We don’t sell generic outsourcing.

Instead, we help founders:

  • build the right team structure from day one
  • keep technical ownership and transparency
  • scale delivery without losing control
  • avoid vendor lock-in and hidden risks

Teams are aligned with the product roadmap, business goals and long-term architecture. Not just short-term velocity.

Dmytro Nasyrov, Founder and CTO at Pharos Production
Dmytro Nasyrov Founder & CTO Let's work together!

Your business results matter

Achieve them with minimized risk through our bespoke innovation capabilities

Your contact details
Please enter your name
Please enter a valid email address
Please enter your message

We use your details only to reply to your request. Data Privacy and Legal Notice

We typically reply within 24 hours

What happens next?

  1. Contact us

    Contact us today to discuss your project. We're ready to review your request promptly and guide you on the best next steps for collaboration

    Same day
  2. NDA

    We're committed to keeping your information confidential, so we'll sign a Non-Disclosure Agreement

    1 day
  3. Plan the Goals

    After we chat about your goals and needs, we'll craft a comprehensive proposal detailing the project scope, team, timeline and budget

    3-5 days
  4. Finalize the Details

    Let's connect on Google Meet to go through the proposal and confirm all the details together!

    1-2 days
  5. Sign the Contract

    As soon as the contract is signed, our dedicated team will jump into action on your project!

    Same day