Background: cmi5 Security Model Evolution
In the IEEE LTSC cmi5 working group, we're currently defining the minimum security rights an Assignable Unit (AU, also known as a Learning Record Provider/LRP) has for reading and writing to the LRS. While the default isolation model (actor + activity + registration scoped) covers most use cases well, we've identified several important scenarios that require expanded permissions.These use cases—including competency assertion, team training, analytics dashboards, and adaptive learning—are documented and discussed here:
https://opensource.ieee.org/ltsc/cmi5-staging/-/issues/34
The Real-World Challenge
In my consulting work, I frequently need to stand up learning systems using various LRS backends (YetAnalytics, Veracity, SCORM Cloud, etc.). A recurring challenge is that most LRS implementations use static API keys that:- Never expire (security risk)
- Allow any actor to be impersonated (privacy violation)
- Cannot be scoped to specific sessions
- Don't support the permission model we're defining in cmi5
The Solution: OAuth JWT Proxy
To validate these concepts and provide a working reference implementation, I've created an xAPI LRS Auth Proxy that implements session-based JWT authentication for cmi5/xAPI systems.How It Works
- LMS requests token - When launching content, the LMS calls the proxy's token API with the learner's actor, registration (session ID), and requested permissions
- Proxy issues JWT - A short-lived (default 1 hour for testing but configurable and API settable), cryptographically signed token scoped to specific actor/activity/registration
- Content uses token - The AU receives this via standard cmi5 fetch, completely transparent to existing content
- Proxy validates & forwards - Each xAPI request is validated against the token's permissions before forwarding to the LRS
Key Features
Non-breaking - Works with existing cmi5 content (AU fetch flow unchanged)
LRS-agnostic - Sits in front of any xAPI-compliant LRS backend
Permission enforcement - Implements the full permission model from the cmi5 use cases
Multi-tenant ready - Supports SaaS deployments with host header routing
Production ready - Written in Go, includes Docker deployment, PostgreSQL backend
Open source - MIT license, comprehensive documentation
Use Cases Enabled
The proxy supports all the permission scopes we've identified:- Default isolation (actor-activity-registration-scoped)
- Course-wide analytics (actor-course-registration-scoped)
- Team training (group-activity-registration-scoped)
- Adaptive learning (actor-activity-all-registrations)
- Certification tracking (actor-cross-course)
- And more...
GitHub Repository
The complete reference implementation is available here:https://github.com/tla-ecosystem/xapi-lrs-auth-proxy
Includes:
- Full Go source code (~1,750 lines)
- Comprehensive architecture documentation
- Testing guide with examples
- Docker deployment ready
- PostgreSQL schema for multi-tenant deployments
Seeking Community Feedback
I'm sharing this with the TLA community for several reasons:- Standards alignment - Does this approach align with the direction of TLA and cmi5?
- Real-world validation - Can others test this with their LRS/LMS combinations?
- Use case coverage - Are there permission scenarios we're missing?
- Implementation feedback - How can we make this more useful for the community?
- LRS vendors on integration approaches
- LMS developers on token issuance workflows
- Content developers on any friction points
- Security professionals on the authentication model