Why This Matters

If you sell paid video and your audience includes a single iPhone, you ship FairPlay Streaming. Safari does not run the Widevine Content Decryption Module, tvOS does not run PlayReady, and the iOS native player only speaks one DRM — FPS. A product manager reading this article will leave knowing exactly why "we use Widevine" is never enough for an OTT launch, and what the credential approval process from Apple does to your launch calendar (review windows of two weeks or more are the 2026 norm). An engineer will leave with the on-the-wire EXT-X-KEY syntax, the EME keySystem string Safari demands, the AVFoundation API the iOS app uses, and the four production bugs that show up the week before launch. A founder weighing risk will leave with a defensible answer to "is FairPlay stronger than Widevine L1?" — short version: structurally yes, because the keys flow into Apple's Secure Enclave on every device that ships an A-series or M-series chip, and Apple has never publicly issued a robustness level the way Google labels L1/L2/L3; either a device runs FPS or it does not, and the ones that do run it inside the same hardware that protects Apple Pay.

This article is the third in a four-part DRM mini-series — DRM 101: why three systems, and why you ship all three is the pillar, Common Encryption (CENC) in depth is the packaging layer, Widevine Security Levels: L1, L2, L3 is the Google side, and PlayReady in depth is the Microsoft side. Read this one to understand Apple.

What FairPlay Streaming Actually Is

Before the wire format, the definition. FairPlay Streaming is a Key Server Module (KSM) protocol plus a client SDK plus a deployment-credential workflow. The KSM is the piece you build and run; it lives behind your existing license-acquisition endpoint and speaks the FPS request/response format. The client SDK is what Apple ships inside every Apple operating system — you do not embed it yourself, the way a web page embeds the Widevine CDM. The deployment credentials are the certificate Apple issues to your team after a manual review of your streaming service.

Three things follow from this design and they shape every FPS decision your team will make.

First, the FPS client is part of the operating system, not part of your app or your web page. On the web, the FPS Content Decryption Module (CDM) is built into Safari and is reachable only via the W3C Encrypted Media Extensions (EME) requestMediaKeySystemAccess call using the key-system string com.apple.fps.1_0 (older variants com.apple.fps.2_0, com.apple.fps.3_0, and the unversioned com.apple.fps exist for different protocol revisions; the versioned form is the production default). In a native iOS or tvOS app you reach FPS via AVContentKeySession, a Foundation class introduced in iOS 11 that supersedes the older AVAssetResourceLoaderDelegate path. Either way the actual cryptography happens inside Apple silicon that your code cannot touch.

Second, Apple does not publish per-device security levels. Google grades Widevine devices L1, L2, or L3 — see our Widevine Security Levels in depth article. Apple does not. A device either supports FPS or it does not, and every device that does supports it with the same trust model: keys land in the Secure Enclave (the dedicated coprocessor that also holds your Apple Pay tokens and Touch ID / Face ID templates), sample decryption happens in hardware, and decoded frames go to the display through Apple's restricted CoreMedia path. There is no "FPS L3" running in software the way desktop Chrome runs Widevine L3. This is partly why FPS-licensed content streams 4K HDR on a Mac while Widevine on the same Mac in Chrome caps at 720p.

Third, deployment credentials require Apple's manual approval. You apply through the FairPlay Streaming credentials portal, Apple reviews your streaming service, and only then does your team gain access to the certificate-creation flow inside the Apple Developer Portal. Each team holds at most two FPS certificates at a time, and as of September 2026 Apple will not provision a new SDK 26 certificate unless one of those slots is empty. The Apple Developer Forums are full of two-and-a-half-week review-time complaints from 2025; plan for that on your launch calendar, not against it.

Three roles in a FairPlay Streaming deployment: Apple (issues certificate and operates SDK), the operator (runs the Key Server Module and the packager), and the device (holds the Secure Enclave and runs the Apple-supplied CDM) Figure 1. The three-party trust chain. Apple issues the certificate and operates the device side; you run the KSM and the packager; the device's Secure Enclave brokers the conversation.

The On-The-Wire Protocol: SPC and CKC

A FairPlay license fetch is a two-message exchange. Both messages are opaque binary blobs from the player's perspective; only your Key Server Module and the device's FPS CDM understand the contents. Apple's FairPlay Streaming Overview (the public PDF that anchors every implementation) defines the message names and the high-level shape; the byte-level grammar is in the FairPlay Streaming Server SDK distributed under NDA.

Message 1 — Server Playback Context (SPC). When a player encounters an encrypted segment, it asks the FPS CDM to generate an SPC. The CDM bundles together the content's key identifier (the KID carried in the EXT-X-KEY tag, which we'll dissect below), a 16-byte anti-replay nonce, an integrity hash of the SPC body, the device's identity payload, and a session key — then encrypts the whole bundle with the public key from your team's FPS certificate. The encrypted result is an SPC. The player base64-encodes it and POSTs it to your license URL.

Message 2 — Content Key Context (CKC). Your Key Server Module receives the SPC, decrypts it with your team's private key (the half of the FPS certificate Apple does not see), and uses the Apple-supplied SDK to:

  1. Verify the SPC's integrity hash and the nonce against your replay-protection window.
  2. Extract the requested KID and look up the actual content key in your database.
  3. Apply business rules — is this user authorised, does the content's policy permit this device class, has the rental window expired, is the user inside a permitted geography.
  4. If all rules pass, ask the SDK to wrap the content key (plus the optional rental-duration and HDCP-enforcement parameters) into a CKC, encrypted using the session key the SPC supplied.

The CKC goes back to the player, the player hands it to the FPS CDM, the CDM unwraps the content key inside the Secure Enclave, and decryption begins. The key is never visible in normal application memory — not in the browser process, not in your iOS app's address space, not on the GPU bus.

The single most useful sentence in this article is the next one. The KSM never sees the content key in clear text on its way to the device. Your KSM holds the content key plaintext (you encrypted the video with it during packaging), but it hands the key to Apple's SDK and the SDK wraps it under a per-session, per-device session key before it leaves your server. An attacker who captures a CKC off the wire cannot extract the content key without also breaking the session key, and the session key only existed for this one license response on this one device.

The SDK 26 announcement bumps three pieces of this exchange:

  • SPC v3 — adds an explicit Protocol Version UUID, a SHA-256 certificate-hash field replacing the SDK 4 SHA-1, and mandatory integrity verification. Older devices keep speaking SPC v1 and v2; your KSM auto-detects the version from the SPC header.
  • RSA-2048 certificates — replacing the SDK 4 RSA-1024 default. Every SDK 26 certificate Apple issues from September 2026 is RSA-2048.
  • Default business rules — the SDK now ships with a reference implementation of the most common business rules (HDCP enforcement, rental windows, lease durations), so the KSM author starts from a working baseline instead of a blank file.
FairPlay Streaming SPC and CKC exchange between the player, the Apple FPS CDM inside the device's Secure Enclave, and the operator-run Key Server Module Figure 2. The SPC/CKC handshake — five steps from "encrypted segment encountered" to "decrypted frame on screen".

The HLS Manifest: How FairPlay Lives Inside an .m3u8

A FairPlay-protected HLS manifest looks almost identical to an ordinary one. The two changes are an extra EXT-X-KEY tag and a specific encryption method.

The minimum syntax for a single-rendition FPS-protected playlist is:

#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:6
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://12345-67890-abcde",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXTINF:6.0,
segment0.m4s
#EXTINF:6.0,
segment1.m4s
...
#EXT-X-ENDLIST

The five attributes worth knowing by heart:

  • METHOD=SAMPLE-AES — tells the player to use sample-level encryption (only the elementary media samples are encrypted; container boxes, timestamps, and codec parameter sets stay in the clear so the player can build a presentation timeline without the key). When the segments are fragmented MP4 (CMAF), the encryption scheme is cbcs from ISO/IEC 23001-7:2023 — AES-128 in CBC mode with a 1:9 encryption pattern (one encrypted block of 16 bytes, then nine unencrypted blocks of 16 bytes, then repeat). When the segments are MPEG-TS, the same SAMPLE-AES method maps to Apple's older MPEG-2 Stream Encryption format documented at the MPEG-2 Stream Encryption Format archive page.
  • URI="skd://..." — the skd: scheme is Apple's signal that this is a FairPlay key URI. The opaque string after skd:// is your content-side KID; the player passes it through to the FPS CDM and to your KSM unchanged. The optional : suffix supplies an Initialization Vector inline if you do not want to ship it inside the entitlement message.
  • KEYFORMAT="com.apple.streamingkeydelivery" — declares the key-format identifier. This is the magic string the player looks for; any other value (or the absence of this tag) means FPS will not engage.
  • KEYFORMATVERSIONS="1" — the only legal value in 2026.
  • #EXT-X-VERSION:6SAMPLE-AES requires HLS protocol version 5 or higher; version 6 is the minimum that supports fMP4 segments. Apple's HLS Authoring Specification, revision 2025-09, mandates fMP4 (CMAF) for new content; MPEG-TS remains supported for legacy ingest only.

A common manifest in 2026 carries two EXT-X-KEY tags side by side — one for FairPlay and one for the Common Encryption Widevine / PlayReady pair, so the same segments can be decrypted by an Apple device via the FPS line and by a Widevine or PlayReady device via the CENC line. Apple's CBCS-only constraint means the underlying bytes are encrypted in cbcs mode, which Widevine and PlayReady have supported since 2018. The era of double-packaging (one set of segments encrypted with cenc AES-CTR for Widevine/PlayReady, another with cbcs for FPS) ended around 2020; in 2026 a single CMAF asset feeds all three DRMs.

#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://kid-uuid",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,...",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="1"

The first tag triggers FairPlay; the second carries a Widevine pssh payload as a data: URI under the Widevine system-id UUID. The player picks the line that matches its key system.

A CMAF fragment encrypted once with the cbcs scheme of ISO/IEC 23001-7, decrypted by FairPlay on an Apple device via the skd line of the manifest and by Widevine on an Android device via the data line Figure 3. Encrypt once, decrypt three times. The cbcs scheme makes single-encode multi-DRM the production default.

Persistent Licenses and Offline Playback

The iOS 10 release in 2016 added persistent FairPlay licenses so a user can download a movie on Wi-Fi at home and play it on a plane. Apple calls the feature Dual Expiry Windows, and the design is worth knowing because every rental product touches it.

When a user starts a download, your KSM issues a CKC with two duration fields attached:

  • Storage duration — the maximum time the license is valid before playback starts, counted from the moment the device persists it. The classic rental example is 30 days: the user has 30 days to actually begin watching the film, otherwise the license auto-invalidates.
  • Playback duration — the maximum wall-clock time the license stays valid after playback starts. The classic rental example is 48 hours from the first frame.

The combined two-number window — 30 days to start, 48 hours to finish — is exactly the "rent, then watch within 48 hours" model that every major OTT service uses. The KSM emits one CKC at download time; the device stores it; the first play triggers an internal clock that the device tracks and the OS enforces. The app cannot extend the playback window without going back to the server for a fresh CKC.

A practical limitation worth flagging in your KSM: there is no API for the iOS app to query the remaining time on a persistent license. Your app has to track the start-of-playback timestamp itself, persist it, and compare to its own copy of the playback duration to display a "47 hours remaining" UI. Apple's AVPersistableContentKeyRequest returns the license blob but not its remaining duration — that's a recurring complaint on the Apple Developer Forums.

The SDK 26 Migration

Apple's announcement of FairPlay Streaming Server SDK 26 at WWDC 2025 set a September-2026 cutover. Every team that ships paid video to Apple devices has to either confirm SDK 5 is still acceptable for their account or migrate the certificate they hold to SDK 26. The four practical changes:

1. Certificate slot economics. Every team can hold at most two FPS certificates at any time. A team that already has both slots occupied with SDK 4.x or SDK 5.x credentials cannot generate a new SDK 26 credential until Apple clears one. The clearing is manual and goes through the same Apple-developer-support channel as the original credential request; plan two-to-four weeks for the round trip in production migrations.

2. RSA-2048 across the board. SDK 4 certificates are RSA-1024; SDK 26 certificates are RSA-2048. Your KSM has to load both, detect the certificate version from the SPC, and respond with the matching CKC format. Apple's reference KSM (now shipped in Swift and Rust) handles this; a hand-rolled KSM from a 2018 implementation does not.

3. SPC v3 integrity protection. SDK 26 devices ask for SPC v3, which includes a mandatory integrity hash field your KSM must verify before processing the request. A KSM that silently ignores an unrecognised field will silently accept tampered SPCs from SDK 26 devices; the SDK 26 reference KSM rejects with a defined error code. Run your fuzz tests against the new code path before the migration.

4. Multiple certificate bundles per KSM. Until SDK 26 a KSM held one certificate per "issuer". The new SDK lets a KSM serve multiple certificate bundles simultaneously, which matters if your operator runs several brands (e.g., a parent OTT plus a couple of skinny bundles) under separate Apple-developer accounts. One KSM instance, several certificate bundles, fewer servers.

The migration is non-disruptive in the steady state — old devices keep speaking older SPC versions, the SDK 26 reference KSM accepts SPC v1 through v3 simultaneously. The disruption is administrative: clearing certificate slots, requesting deployment approvals, and re-signing the trust chain.

Where FairPlay Sits Next to Widevine and PlayReady

The 2026 production map is simple and worth a row table.

CriterionFairPlayWidevinePlayReady
OwnerAppleGoogleMicrosoft
Required foriOS, iPadOS, tvOS, macOS Safari, watchOS, visionOSAndroid, Chromium-based browsers, Chromecast, Android TVWindows native apps, Edge Legacy, Xbox, many Tizen / webOS Smart TVs
ContainerHLS (CMAF or MPEG-TS)DASH (CENC) or HLS (CMAF, CBCS)DASH (CENC) or HLS (CMAF)
CENC schemecbcs onlycenc or cbcscenc or cbcs
Browser EME key systemcom.apple.fps.1_0 (also 2_0, 3_0)com.widevine.alphacom.microsoft.playready
Public security levelsNone published; trust anchored in Secure EnclaveL1 / L2 / L3 publishedSL150 / SL2000 / SL3000 published
Certificate acquisitionApple manual approval, ~2-week reviewSelf-serve via Widevine partner portalManual via Microsoft license programme
Persistent / offlineYes — Dual Expiry Windows since iOS 10Yes — persistent-license session typeYes — non-persistent and persistent licenses
2026 minimum SDKSDK 26 (September 2026 cutover)Modular Widevine 5.x (since 2014)PlayReady 4.5 (Smart TVs) / 4.6 (Edge)
The practical pairing every OTT product ships is Widevine + FairPlay as the two-DRM minimum: between them they cover every Chrome, Firefox, Edge-Chromium, Safari, Android, iOS, Smart TV running Android TV, and Apple TV. PlayReady is added when the audience includes Tizen / webOS Smart TVs at 4K (where the PlayReady SL3000 path is the only one that unlocks UHD), Xbox consoles, or Windows-native apps with strict studio contracts. See the Common Encryption (CENC) in depth article for how all three sit inside the same encrypted CMAF file. Side by side comparison of FairPlay, Widevine and PlayReady on owner, encryption mode, key system identifier, security level model, and 2026 minimum SDK Figure 4. The three-DRM comparison matrix every product team prints and pins above the desk.

A Worked Numeric Example: License Server Throughput

Assume an OTT product launching with 50,000 concurrent viewers at peak. Each viewer fetches one CKC at session start and a refresh CKC roughly every 24 hours of a continuous binge (most products configure session keys to expire on a 24-hour ceiling). Peak is one viewer-second of license traffic per new login plus a slow background of renewals.

Single-session license issuance: 1 SPC parse + 1 RSA-2048 decrypt + 1 CKC build + 1 RSA-2048 sign ≈ 8 ms of CPU on a modern Xeon core. Concurrent capacity per core at 100% utilisation:

1 core × 1000 ms / 8 ms per license = 125 licenses / second

A 50,000-viewer launch with a 10-minute warm-up window means roughly 50,000 SPCs in 600 seconds, or 83 SPCs/second average, with a 3× peak burst of 250 SPCs/second when the second-screen audience all hits play at the start of a live event.

To handle 250 SPCs/second with a 50% headroom target:

250 SPCs / sec × 1.5 / 125 SPCs / (sec · core) = 3 cores

A single 4-core KSM instance covers a 50,000-viewer event with margin. Two KSM instances behind a load balancer cover failover. The license server is almost never the bottleneck in a streaming launch; the certificate-acquisition calendar is.

Common Mistakes (And How to Catch Them Before Production)

Pitfall: starting the FPS certificate request after the launch date is set.
Apple's manual review window for FPS deployment credentials runs two weeks or more in 2026, and that window does not start until your team has submitted a description of the streaming service that satisfies Apple's "service to consumers" rule. Third-party agencies acting on behalf of a content owner are explicitly rejected. The single biggest cause of a slipped OTT launch is "we'll request the FPS cert in sprint 4". Request it in sprint 1.
Pitfall: the wrong EME key-system string in Safari.
Safari's FPS CDM only registers under com.apple.fps.1_0 (with 2_0 and 3_0 reserved for protocol upgrades — the current production browser surface is still 1_0). The unversioned com.apple.fps will work on some Safari versions and silently fail on others, and the failure mode is a MEDIA_ERR_SRC_NOT_SUPPORTED in the browser console with a -42676 error at the KSM — which sends every debugger off chasing the server when the fix is one line of EME config in the player.
Pitfall: keeping MPEG-TS segments for FPS-only deliveries in 2026.
Apple's HLS Authoring Specification (revision 2025-09) requires fMP4 (CMAF) for new content; MPEG-TS is supported only for legacy archive playback. Teams who keep an MPEG-TS-only origin "because Apple devices play it fine" end up with a forked packaging pipeline for the first multi-DRM deal they sign. Pick CMAF + cbcs once.
Pitfall: assuming a successful SPC parse means a happy device.
The CKC has to include the right HDCP-enforcement flag, the right rental-duration values, the right lease bits, and (under SDK 26) the right SPC-v3 integrity-confirmation field. A device that receives a syntactically valid CKC with the wrong policy fields will silently fall back to 480p or refuse to play at all, depending on the bit. Production-grade KSMs run a daily smoke test against a fleet of physical Apple devices precisely because the failures are silent.

Where Fora Soft Fits In

We have shipped FairPlay-protected OTT, telemedicine, e-learning, and surveillance products on Apple platforms since the 2015 launch of the modular FPS architecture, across iOS, iPadOS, tvOS, macOS, and visionOS. The work that earns its money is rarely the KSM code — Apple's reference implementations are good — it is the certificate-request choreography with Apple, the dual-DRM CMAF packaging that lets one origin feed FPS plus Widevine plus PlayReady from a single encode, the iOS app's AVContentKeySession integration, the offline-rental UX with persistent licenses and dual-window expiry, and the device-by-device QA matrix across the Apple silicon generations. We build those things as a default, not an extra.

What to Read Next

CTA

Talk to a streaming engineer — scope a FairPlay-protected OTT launch with our team. · See our case studies — production OTT, telemedicine, and e-learning work shipped under Fora Soft's portfolio. · Download the FairPlay Streaming deployment checklista one-page reference covering the certificate request flow, the SDK 26 migration steps, the EME and AVContentKeySession code paths, and four pitfalls that ship to production.

References

  1. Apple, "FairPlay Streaming Overview", developer.apple.com (PDF, anchor document) — the public-facing PDF that defines the SPC / CKC message names, the certificate model, and the deployment-credential workflow. The byte-level grammar lives in the FPS Server SDK distributed under NDA. (First-party, Apple — Tier 1 for Apple-platform behaviour.)
  2. Apple, "FairPlay Streaming" landing page and SDK 26 release notes, developer.apple.com — the canonical SDK download and SDK 26 feature list (SPC v3, multiple certificate bundles, RSA-2048, default business rules). (First-party, Apple — Tier 1.)
  3. Apple, "HLS Authoring Specification for Apple Devices", revision 2025-09 — the normative HLS profile that mandates fMP4 (CMAF) for new content and confirms SAMPLE-AES / cbcs as the FPS encryption baseline. (First-party, Apple — Tier 1.)
  4. IETF RFC 8216, "HTTP Live Streaming", R. Pantos and W. May, August 2017 — the IETF specification that defines #EXT-X-KEY, METHOD=SAMPLE-AES, KEYFORMAT, and KEYFORMATVERSIONS. (Standards body, IETF — Tier 1. The HLS-2nd-Edition revision lives at draft-pantos-hls-rfc8216bis and is the active update track.)
  5. ISO/IEC 23001-7:2023, "Common encryption in ISO base media file format files" (3rd edition) — the controlling document for the cbcs and cenc encryption schemes. FairPlay uses cbcs exclusively. Catalogue page is open; the normative PDF is paywalled. (Standards body, ISO/IEC — Tier 1.)
  6. W3C Encrypted Media Extensions, Recommendation 18 September 2017 — defines requestMediaKeySystemAccess and the key-system string contract Safari uses for com.apple.fps.1_0. (Standards body, W3C — Tier 1.)
  7. Apple, "MPEG-2 Stream Encryption Format for HTTP Live Streaming", archive page — the legacy MPEG-TS sample-encryption format used before fMP4 became the HLS default. (First-party, Apple — Tier 1 for legacy MPEG-TS deployments.)
  8. Apple Developer Forums, "FairPlay Streaming" tag — the authoritative public Q&A for credential-review timing, SDK migration questions, and platform-specific debugging. Approval review windows of "more than two weeks" are confirmed in multiple 2025 threads. (First-party, Apple — Tier 3 for engineering operations colour.)
  9. Apple, "AVContentKeySession" reference, developer.apple.com/documentation — the AVFoundation API for FairPlay key requests in native iOS, iPadOS, tvOS, watchOS, and visionOS apps. (First-party, Apple — Tier 1.)
  10. Bitmovin, "How does FairPlay work?", developer.bitmovin.com — the most accurate vendor-published walk-through of the FPS handshake and the EME key-system string. Used to cross-check Apple's PDF on points the PDF leaves implicit. (First-party engineering blog — Tier 3.)
  11. Big Blue Marble, "Cloud DRM Supports FairPlay SDK 26" — vendor confirmation of the September-2026 SDK 26 cutover, the RSA-2048 upgrade, and the multiple-certificate-bundle support. (First-party engineering blog — Tier 4.)