DRM and token auth testing
Most commercial streaming platforms protect content with either signed URL tokens, session-bound authentication cookies, or full DRM systems (Widevine, FairPlay, PlayReady). Under load, each of these introduces failure modes that plain unauthenticated tests never reveal: license server saturation, token generation throughput limits, auth middleware latency spikes, and token expiry races. This page explains how to include auth and DRM requests in your MaxoPerf streaming tests.
Before you start
Section titled “Before you start”- Read HLS and DASH manifest and segment testing for the base player simulation pattern.
- Read Manage test secrets to understand how to inject API keys and tokens without hard-coding them in your test files.
Signed URL and tokenized segment delivery
Section titled “Signed URL and tokenized segment delivery”Signed URLs embed an auth token (HMAC signature, JWT, or CDN-specific token) in the query string of each manifest and segment URL. The CDN or edge validates the token before serving the response.
What can fail under load
Section titled “What can fail under load”| Component | Failure mode |
|---|---|
| Token generation service | Cannot issue enough tokens per second for all concurrent sessions; returns 429 or 503 |
| CDN token validation | Clock skew or token cache miss causes valid tokens to be rejected; 403 spike |
| Token expiry | Short-lived tokens expire mid-session; later segment requests fail with 403 |
| Shared secret rotation | New tokens use the new secret before CDN edge nodes have fetched it; transient 403 |
Simulating signed URL auth in MaxoPerf
Section titled “Simulating signed URL auth in MaxoPerf”For tokens that are static during a test (pre-issued, long-lived for test purposes), embed the token in the URL directly using a MaxoPerf secret:
scenarios: signed-url-viewer: requests: # Token is embedded in the URL query string # Use a MaxoPerf secret for the token value - label: master-manifest url: "https://cdn.example.com/stream/master.m3u8?token=${CDN_TOKEN}&expires=9999999999" method: GET
- label: variant-playlist url: "https://cdn.example.com/stream/720p/playlist.m3u8?token=${CDN_TOKEN}&expires=9999999999" method: GET
- label: segment url: "https://cdn.example.com/stream/720p/seg-0001.ts?token=${CDN_TOKEN}&expires=9999999999" method: GET - label: segment url: "https://cdn.example.com/stream/720p/seg-0002.ts?token=${CDN_TOKEN}&expires=9999999999" method: GET think-time: 4sSet CDN_TOKEN in MaxoPerf secrets. This approach tests whether the CDN correctly validates tokens under load but does not test token generation throughput.
Testing token generation throughput
Section titled “Testing token generation throughput”If your platform issues a new token per session at session start (a common pattern for short-lived tokens), model the token request at the start of each VU iteration:
scenarios: session-token-then-stream: requests: # Step 1 — get a session token - label: get-session-token url: https://auth.example.com/v1/stream-token method: POST headers: Authorization: "Bearer ${API_KEY}" Content-Type: application/json body: '{"contentId": "event-2026-final", "userId": "${USER_ID}"}' extract-jsonpath: cdn_token: $.token expires_at: $.expiresAt
# Step 2 — use token for streaming requests - label: master-manifest url: "https://cdn.example.com/stream/master.m3u8?token=${cdn_token}" method: GET
- label: variant-playlist url: "https://cdn.example.com/stream/720p/playlist.m3u8?token=${cdn_token}" method: GET
- label: segment url: "https://cdn.example.com/stream/720p/seg-0001.ts?token=${cdn_token}" method: GET - label: segment url: "https://cdn.example.com/stream/720p/seg-0002.ts?token=${cdn_token}" method: GET think-time: 4sThe get-session-token label will appear separately in your MaxoPerf results. You can spot token-service saturation by watching get-session-token p95 latency — rising latency here predicts session start failures under load before the streaming layer is even reached.
Simulating token expiry
Section titled “Simulating token expiry”To test token expiry behavior, issue a token with a short TTL (e.g., 60 seconds) and model a viewer session longer than that TTL. The later segment requests will fail with 403 — and your test result should show that failure and give you the signal to add token renewal logic to your player or middleware.
scenarios: short-lived-token-viewer: requests: - label: get-short-token url: https://auth.example.com/v1/stream-token?ttl=60 method: POST body: '{"contentId": "event-final"}' extract-jsonpath: short_token: $.token
- label: master-manifest url: "https://cdn.example.com/stream/master.m3u8?token=${short_token}" method: GET - label: segment url: "https://cdn.example.com/stream/720p/seg-0001.ts?token=${short_token}" method: GET
# ... segments continue for 90 seconds total (past the 60s token TTL) # Segments after 60s should return 403 — confirming token expiry behavior - label: segment-after-expiry url: "https://cdn.example.com/stream/720p/seg-0016.ts?token=${short_token}" method: GET think-time: 4sAfter the run, filter the Log tab in MaxoPerf for 403 responses on segment-after-expiry to confirm that expiry is enforced correctly and at the expected time boundary.
DRM license server load testing
Section titled “DRM license server load testing”DRM systems (Widevine, FairPlay, PlayReady) require the player to obtain a license before decrypting and playing content. A license request is an HTTP POST to a license server that typically involves:
- A license challenge (generated by the player’s CDM) sent as a POST body.
- The license server validating the viewer’s entitlement.
- A license blob returned and decrypted by the CDM.
Modeling DRM license requests under load
Section titled “Modeling DRM license requests under load”License requests happen once at session start (for a playback session) or periodically (for rotating keys). Model them as an additional labeled request at the start of each VU session:
scenarios: drm-protected-viewer: requests: # DRM license acquisition — happens once per session - label: drm-license-request url: https://license.example.com/v1/widevine method: POST headers: Authorization: "Bearer ${SESSION_TOKEN}" Content-Type: application/octet-stream # Use a pre-captured license challenge blob for load testing # Real CDM challenge is device-specific; use a test challenge that the license server accepts body: "${DRM_CHALLENGE_B64_ENCODED}" assert: - equals: subject: http-code value: '200'
# Session setup: manifest and variant playlist - label: master-manifest url: "https://cdn.example.com/stream/master.m3u8?token=${SESSION_TOKEN}" method: GET - label: variant-playlist url: "https://cdn.example.com/stream/720p/playlist.m3u8?token=${SESSION_TOKEN}" method: GET
# Segment loop - label: segment url: "https://cdn.example.com/stream/720p/seg-enc-0001.m4s" method: GET - label: segment url: "https://cdn.example.com/stream/720p/seg-enc-0002.m4s" method: GET think-time: 4sWhat to watch for in DRM load test results
Section titled “What to watch for in DRM load test results”| Label | Signal |
|---|---|
drm-license-request p95 rising | License server is saturating under concurrent session starts |
drm-license-request error rate > 0 | License server rejecting requests — check entitlement service, quota limits |
drm-license-request p95 OK, segment 4xx | License is granted but CDN key validation is failing — key rotation or token scope issue |
At live-event scale, all viewers request a license within the first 60 seconds of kickoff. This creates a license server spike identical in profile to the CDN manifest spike. Size your license server autoscaling to handle the same concurrency as your CDN manifest server.
Do / don’t
Section titled “Do / don’t”Do:
- Test token generation separately from segment delivery — label the token request so you can see its latency independently.
- Use MaxoPerf secrets for API keys, token signing secrets, and test credentials. Never hard-code them in test files.
- Simulate token expiry to verify your renewal logic handles it gracefully before real viewers encounter it.
Don’t:
- Assume DRM license server capacity is free — license servers have CPU-intensive key derivation per request and are frequently the bottleneck at live-event scale.
- Use production DRM license server credentials in load tests without a strict rate-limit plan and sign-off from your operations team.
- Forget to test the CDN edge’s token validation behavior — CDN token validation is a separate code path from origin auth, and edge capacity limits can differ significantly.
Where to go next
Section titled “Where to go next”- Concurrent viewers load — modeling the session startup spike that drives license server load.
- Live event streaming load — the kickoff spike that hits license servers hardest.
- Cookbook: manage test secrets — injecting auth credentials safely.
- Daily streaming scenarios — how DRM auth fits into complete scenario patterns.