A reference implementation of a secure authentication proxy for cmi5 and xAPI learning systems.
New to Windows development? We've created a complete step-by-step guide just for you:
π Windows Quick Start Guide
Covers:
- Installing Go on Windows
- Setting up PATH correctly
- Proper file structure
- Building with PowerShell
- Testing on Windows
- Common Windows-specific issues
This proxy provides:
- Session-scoped JWT tokens instead of static API keys
- cmi5 permission enforcement (actor, activity, registration scoping)
- Multi-tenant support via Host header routing
- LRS abstraction - swap any xAPI-compliant LRS backend
- Centralized security - one place to manage authentication
[LMS] β Token API β Issues JWT
β
[Content] β xAPI Proxy β Validates JWT β [LRS]
- β JWT-based authentication with short-lived tokens
- β Actor, activity, and registration scoping
- β Permission enforcement per cmi5 specification
- β Group actor support for team training
- β Audit logging
- β Host header-based tenant routing
- β Tenant-specific JWT secrets
- β Tenant-specific LRS backends
- β Per-tenant permission policies
- β Single-tenant mode (on-premises)
- β Multi-tenant mode (SaaS)
- β Database-backed (PostgreSQL) or config file
- β Redis caching (optional)
- β Docker support
Windows users: See WINDOWS_QUICKSTART.md for detailed setup.
1. Clone the repository:
git clone https://github.com/tla-ecosystem/xapi-lrs-auth-proxy.git
cd xapi-lrs-auth-proxy2. Create configuration:
cp config.example.yaml config.yaml
# Edit config.yaml with your LRS detailsMinimal config.yaml:
mode: single-tenant
server:
port: 8080
lrs:
endpoint: https://lrs.example.com/xapi/
username: admin
password: your-lrs-password
auth:
jwt_secret: your-256-bit-secret-key-here
jwt_ttl_seconds: 3600
lms_api_keys:
- your-lms-api-key3. Build and run:
# Download dependencies
go mod download
# Build
go build -o xapi-proxy cmd/proxy/main.go
# Run
./xapi-proxy --config config.yamlWindows:
go mod download
go build -o xapi-proxy.exe ./cmd/proxy
.\xapi-proxy.exe --config config.yaml4. Test:
# Health check
curl http://localhost:8080/health
# Request token
curl -X POST http://localhost:8080/auth/token \
-H "Authorization: Bearer your-lms-api-key" \
-H "Content-Type: application/json" \
-d '{
"actor": {"mbox": "mailto:learner@example.com"},
"registration": "uuid-here",
"activity_id": "https://example.com/activity",
"permissions": {
"write": "actor-activity-registration-scoped",
"read": "actor-activity-registration-scoped"
}
}'1. Setup database:
psql -U postgres -f schema.sql2. Run in multi-tenant mode:
./xapi-proxy --multi-tenant --db "postgresql://user:pass@localhost/xapi_proxy"3. Create tenants via Admin API:
curl -X POST http://localhost:8080/admin/tenants \
-H "Authorization: Bearer admin-token" \
-d '{
"tenant_id": "acme-corp",
"hosts": ["acme.proxy.example.com"],
"lrs": {
"endpoint": "https://lrs.acme.com/xapi/",
"username": "admin",
"password": "password"
}
}'# Single-tenant
docker-compose up -d proxy-single
# Multi-tenant (with PostgreSQL)
docker-compose up -d proxy-multi postgres redisIssue Token:
POST /auth/token
Authorization: Bearer <LMS-API-Key>
Content-Type: application/json
{
"actor": {
"objectType": "Agent",
"mbox": "mailto:learner@example.com"
},
"registration": "uuid-here",
"activity_id": "https://example.com/activity",
"course_id": "safety-training",
"permissions": {
"write": "actor-activity-registration-scoped",
"read": "actor-course-registration-scoped"
}
}
Response: {
"token": "eyJhbGci...",
"expires_at": "2026-01-17T15:30:00Z"
}Post Statements:
POST /xapi/statements
Authorization: Bearer <JWT-token>
Content-Type: application/json
[{
"actor": {...},
"verb": {...},
"object": {...},
"context": {
"registration": "uuid-here"
}
}]All standard xAPI endpoints are supported:
POST/PUT/GET /xapi/statementsPOST/PUT/GET/DELETE /xapi/activities/statePOST/PUT/GET/DELETE /xapi/activities/profilePOST/PUT/GET/DELETE /xapi/agents/profileGET /xapi/about
actor-activity-registration-scoped- Write/read only own activity in current session
actor-course-registration-scoped- Read across entire course (current session)
actor-activity-all-registrations- Read across all attempts
group-activity-registration-scoped- Group actor with member validation
actor-cross-course-certification- Read across multiple courses
Benchmarks:
- Token issuance: 10,000+ tokens/second
- Statement validation: 50,000+ statements/second
- Proxy overhead: <0.1ms per request
- Horizontal scaling: Linear up to LRS capacity
Capacity:
- Single instance: 10,000 concurrent users
- Multi-tenant: 1,000+ tenants per instance
Getting Started:
- πͺ Windows Quick Start - Step-by-step for Windows
- π README.md - This file
- π§ͺ TESTING.md - Comprehensive testing guide
Technical:
- ποΈ ARCHITECTURE.md - Design decisions, data flows, security model
- π€ CONTRIBUTING.md - How to contribute
- π PROJECT_SUMMARY.md - Executive overview
# Standard build
go build -o xapi-proxy cmd/proxy/main.go
# With make
make build
# Windows
go build -o xapi-proxy.exe ./cmd/proxy
# Docker
docker build -t xapi-proxy .Troubleshooting build issues? See WINDOWS_QUICKSTART.md
# Run all tests
go test ./...
# With make
make test
# Use test script
./test-client.shWindows: See WINDOWS_QUICKSTART.md for PowerShell test commands.
- β cmi5 specification - Implements permission model
- β xAPI 1.0.3 - Full xAPI endpoint support
- β JWT RFC 7519 - Standard token format
- β OAuth 2.0 patterns - Bearer token authentication
MIT License - see LICENSE file
This is a reference implementation for the cmi5/xAPI community. Contributions welcome!
See CONTRIBUTING.md for guidelines.
- GitHub Issues: https://github.com/tla-ecosystem/xapi-lrs-auth-proxy/issues
- TLA Forum: https://discuss.tlaworks.com/
- IEEE LTSC: cmi5 working group
- IEEE LTSC cmi5 Working Group - Bill McDonald and Andy Johnson
- inXsol LLC , PoweredLearning Corp, SimplestData LLC
Quick Links:
- πͺ Windows Setup Guide
- π Full Documentation
- π§ͺ Testing Guide
- π Report Issues