Day 1 · 25 min read

Licenses, Keys, Rotation & Renewals

Persistent vs streaming licenses, key rotation, renewal flows.

What is in a licence?

A Widevine licence is a signed, opaque binary. The CDM unwraps it inside the TEE; the rich OS only ever sees ciphertext. Conceptually it carries:

The integrator never handles raw content keys at runtime. They're created by the packager, looked up server-side by KID, and wrapped by the SDK before the licence leaves the server.

Streaming vs persistent licences

StreamingPersistent
Stored on device?No — kept in CDM memory for the sessionYes — written to secure storage, survives reboot
Use casesVOD playback, liveDownload-to-go, in-flight content, EST
Studio scrutinyStandardHigher — devices must be approved for offline by content owner
Policy specificsExpires with sessionlicense_duration_seconds + playback_duration_seconds after first play

A 48-hour rental looks like:

license_duration_seconds  = 30 * 24 * 3600   # 30 days to start
playback_duration_seconds = 48 * 3600        # 48 hours after first play
can_persist               = true
can_renew                 = false (typical for rental)

Renewal

The CDM doesn't try to "be smart" about expiry on its own. Instead, when a licence is approaching expiry — or the policy says renewal is required after N seconds of playback — it emits a renewal message. The application's job is to ferry that message to the licence server like any other licence request, and feed the response back via session.update() (web) or provideKeyResponse() (Android).

Licence renewal mid-playback
Step 1 of 4

CDMDetects expiry approaching

The original licence was issued with policies like renewal_recovery_duration_seconds. The CDM tracks playback time and emits a renewal request before the keys go stale.

If the application ignores the renewal message, playback stops at the moment the original licence expires. This is one of the most common integration bugs reviewers flag.

Common pitfall

An EME message event is not always a brand-new licence request. Always check the messageType (license-request, license-renewal, license-release, individualization-request) and act accordingly.

Key rotation

In live streams, the packager can rotate content keys on a fixed cadence (every N seconds). Each new key window introduces a new KID. The CDM picks up the change and asks for a fresh licence covering the new KIDs.

Why bother? It limits the value of any individual stolen key. If a key is exfiltrated, only the few seconds of content protected by it are exposed. Combine rotation with renewal and the licence server can also revoke playback mid-session by simply refusing to issue the next licence.

t=0    KID = K1   keys: K1=...
t=300  KID = K2   keys: K2=...   ← new licence request (or renewal carrying K2)
t=600  KID = K3   keys: K3=...

Putting it together

Online VOD: streaming licence, no rotation, possibly renewal if duration is long.

Live channel: streaming licence, key rotation, frequent renewals. Sometimes one licence covers multiple upcoming KIDs to absorb network blips.

EST / download-to-go: persistent licence, long licence duration, no expiry on playback once started, persistence allowed.

Subscription rental: persistent + playback_duration_seconds once first play occurs.

Exam tip

Be ready to map a business requirement ("48-hour rental from purchase, 24-hour playback once started, downloadable") to the policy fields that express it. The exam asks this kind of mapping question repeatedly.

No questions yet for licenses-and-keys. Add some in content/questions/licenses-and-keys.json.