DRM and token auth testing
Most commercial streaming platforms protect content with signed URL tokens, session-bound authentication cookies, or full DRM systems (Widevine, FairPlay, PlayReady). Under load, each of these adds failure modes that plain unauthenticated tests never show: license server saturation, token generation throughput limits, auth middleware latency spikes and token expiry races. This page shows how to add auth and DRM requests to 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 learn 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”If the token stays the same for the whole test (pre-issued, long-lived for test purposes), put it straight into the URL with 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 checks that the CDN validates tokens correctly under load. It does not test token generation throughput.
Testing token generation throughput
Section titled “Testing token generation throughput”If your platform issues a new token for each session at session start (common 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 shows up on its own in your MaxoPerf results. Watch get-session-token p95 latency to spot token-service saturation. Rising latency here predicts session start failures under load, before any request reaches the streaming layer.
Simulating token expiry
Section titled “Simulating token expiry”To test token expiry, issue a token with a short TTL (e.g., 60 seconds) and model a viewer session longer than that TTL. The later segment requests fail with a 403 response. Your test result should show that failure, which tells you 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. This confirms that expiry is enforced, and at the expected time.
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 extra 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 the entitlement service and quota limits |
drm-license-request p95 OK, segment 4xx | License is granted but CDN key validation is failing: a key rotation or token scope issue |
At live-event scale, all viewers request a license within the first 60 seconds of kickoff. The license server spike has the same profile as the CDN manifest spike. Size your license server autoscaling for 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 on its own.
- Use MaxoPerf secrets for API keys, token signing secrets, and test credentials. Never hard-code them in test files.
- Simulate token expiry to check that your renewal logic handles it before real viewers run into it.
Don’t:
- Assume DRM license server capacity is free. License servers do CPU-intensive key derivation on every request and are often 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 token validation at the CDN edge. It runs on a separate code path from origin auth, and edge capacity limits can differ a lot.
Where to go next
Section titled “Where to go next”- Concurrent viewers load: model 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: inject auth credentials safely.
- Daily streaming scenarios: how DRM auth fits into full scenario patterns.