

# Content encryption and DRM in AWS Elemental MediaPackage
<a name="using-encryption"></a>

Protect your content from unauthorized use through content encryption and digital rights management (DRM). AWS Elemental MediaPackage uses the [AWS Secure Packager and Encoder Key Exchange (SPEKE) API](https://aws.amazon.com/media/tech/speke-basics-secure-packager-encoder-key-exchange-api/) to facilitate content encryption and decryption by a DRM provider. Using SPEKE, the DRM provider supplies encryption keys to MediaPackage through the SPEKE API. The DRM provider also supplies licenses to supported media players for decryption. For more information about how SPEKE is used with services and features running in the cloud, see [AWS cloud-based architecture](https://docs.aws.amazon.com/speke/latest/documentation/what-is-speke.html#services-architecture) in the *Secure Packager and Encoder Key Exchange API Specification guide*.

## Limitations and requirements
<a name="encryption-requirements"></a>

When implementing content encryption for MediaPackage, refer to the following limitations and requirements:
+ Use the AWS Secure Packager and Encoder Key Exchange (SPEKE) API to facilitate integration with a digital rights management (DRM) system provider. For information about SPEKE, see [What is Secure Packager and Encoder Key Exchange?](https://docs.aws.amazon.com/speke/latest/documentation/what-is-speke.html)
+ Your DRM system provider must support SPEKE. For a list of DRM providers that support SPEKE, see the [Get on board with a DRM platform provider](https://docs.aws.amazon.com/speke/latest/documentation/customer-onboarding.html#choose-drm-provider) topic in the *AWS Elemental MediaPackage User Guide*. Your DRM provider can help you set up DRM encryption use in MediaPackage.
+ Use MediaPackage to encrypt live content. 

## Container and DRM system support with SPEKE
<a name="encryption-choosing-speke-version"></a>

MediaPackage supports [SPEKE Version 2.0](https://docs.aws.amazon.com/speke/latest/documentation/the-speke-api-v2.html) which uses multiple, distinct encryption keys for audio and video tracks and uses [Content Protection Information Exchange (CPIX) Version 2.3](https://dashif.org/docs/CPIX2.3/Cpix.html). For more information about SPEKE Version 2.0 encryption configurations, see [Encryption presets in AWS Elemental MediaPackage](drm-content-speke-v2-presets.md).

**Supported containers and DRM systems**

The following table lists the different containers and digital rights management (DRM) systems that SPEKE Version 2.0 supports.


| SPEKE Version 2.0 – Support matrix for container and DRM system | Apple FairPlay | ClearKey AES-128 | Google Widevine | Microsoft PlayReady | Irdeto | 
| --- | --- | --- | --- | --- | --- | 
| TS container |  √ Supports SAMPLE-AES  |  √ Supports AES-128  |  Not supported  |  Not supported  |  Not supported  | 
| CMAF container |  √ Supports cbcs encryption  |  Not supported  |  √ Supports cbcs and cenc encryption  |  √ Supports cbcs and cenc encryption  |  √ Supports cenc encryption  | 

**Supported DRM system IDs**

The following table lists the different DRM [system IDs](https://dashif.org/identifiers/content_protection/) that MediaPackage supports.


| System IDs – Support matrix for DRM system | Apple FairPlay | ClearKey AES-128 | Google Widevine | Microsoft PlayReady | Irdeto | 
| --- | --- | --- | --- | --- | --- | 
|  | 94ce86fb-07ff-4f43-adb8-93d2fa968ca2 | 3ea8778f-7742-4bf9-b18b-e834b2acbd47 | edef8ba9-79d6-4ace-a3c8-27dcd51d21ed | 9a04f079-9840-4286-ab92-e65be0885f95 | 80a6be7e-1448-4c37-9e70-d5aebe04c8d2 | 

## Deploying SPEKE
<a name="encryption-deploying-speke"></a>

Your digital rights management (DRM) system provider can help you get set up to use DRM encryption in MediaPackage. Generally, the provider gives you a SPEKE gateway to deploy in your AWS account in the same AWS Region where MediaPackage is running. For information about configuring encryption settings for your endpoint, see [ encryption fields](https://docs.aws.amazon.com/mediapackage/latest/ug/endpoints-encryption.html).

If you must build your own API Gateway to connect MediaPackage to your key service, you can use the [SPEKE Reference Server](https://github.com/awslabs/speke-reference-server) available on GitHub as a starting point.

The following sections provide guidance on how to implement content encryption using SPEKE for MediaPackage.

**Topics**
+ [Limitations and requirements](#encryption-requirements)
+ [Container and DRM system support with SPEKE](#encryption-choosing-speke-version)
+ [Deploying SPEKE](#encryption-deploying-speke)
+ [Implementing SPEKE v2.0](implementing-speke-v2.md)
+ [Content key encryption](drm-content-key-encryption.md)
+ [Key rotation](drm-content-key-rotation.md)
+ [Managing DRM segment metadata](drm-segment-metadata-management.md)
+ [Exclude session keys](drm-session-key-exclusion.md)
+ [Encryption presets](drm-content-speke-v2-presets.md)

# Implementing SPEKE v2.0 with AWS Elemental MediaPackage
<a name="implementing-speke-v2"></a>

This topic supplements the [SPEKE API v2 — Customizations and constraints to the DASH-IF specification](https://docs.aws.amazon.com/speke/latest/documentation/speke-constraints-v2.html) with practical implementation guidance verified through production integration testing with AWS Elemental MediaPackage v2.

**Note**  
This guide does not cover [SPEKE API v2 — Content Key Encryption](https://docs.aws.amazon.com/speke/latest/documentation/content-key-encryption-v2.html). Examples show content keys returned in `pskc:PlainValue` (cleartext base64), protected by HTTPS transport encryption.

**Topics**
+ [HTTP protocol requirements](#speke-v2-http-requirements)
+ [CPIX document structure](#speke-v2-cpix-structure)
+ [DRM system signaling](#speke-v2-drm-signaling)
+ [Key delivery to players](#speke-v2-key-delivery)
+ [Testing and verification](#speke-v2-testing)
+ [Implementation checklist](#speke-v2-checklist)

## HTTP protocol requirements
<a name="speke-v2-http-requirements"></a>

**Request headers (from MediaPackage)**


| Header | Required | Value | 
| --- | --- | --- | 
| Content-Type | Yes | application/xml | 
| X-Speke-Version | Yes | 2.0 | 

**Response headers (from key provider)**


| Header | Required | Value | 
| --- | --- | --- | 
| Content-Type | Yes | application/xml | 
| X-Speke-Version | Yes | Echo back the request value | 
| X-Speke-User-Agent | Yes | Your server identifier | 

**Error responses (HTTP 422)**


| Condition | Error message | 
| --- | --- | 
| Missing contentId | Missing CPIX@contentId | 
| Missing version | Missing CPIX@version | 
| Unsupported version | Unsupported CPIX@version | 
| Missing encryption scheme | Missing ContentKey@commonEncryptionScheme for KID \$1id\$1 | 
| Mixed encryption schemes | Non compliant ContentKey@commonEncryptionScheme combination | 
| Unsupported SPEKE version | Unsupported SPEKE version | 

## CPIX document structure
<a name="speke-v2-cpix-structure"></a>

Every SPEKE v2.0 exchange uses CPIX v2.3 XML with the namespaces `xmlns:cpix="urn:dashif:org:cpix"` and `xmlns:pskc="urn:ietf:params:xml:ns:keyprov:pskc"`.

### Root element: cpix:CPIX
<a name="speke-v2-cpix-root"></a>


| Attribute | Required | Description | 
| --- | --- | --- | 
| contentId | Yes | Content identifier from MediaPackage. Must not be empty. | 
| version | Yes | Must be 2.3. Return error if missing or unsupported. | 

The key provider must NOT modify `contentId` or `version` in the response. However, the key provider may override the `kid` value on `ContentKey` elements — see [Overriding the key identifier](https://docs.aws.amazon.com/speke/latest/documentation/kid-override-v2.html).

### ContentKeyList (mandatory)
<a name="speke-v2-content-key-list"></a>

Contains one or more `ContentKey` elements. Each represents an encryption key.


| Attribute | Required | Description | 
| --- | --- | --- | 
| kid | Yes | Key ID in UUID format | 
| commonEncryptionScheme | Yes | One of: cenc, cbc1, cbcs | 
| explicitIV | Optional | Base64-encoded 16-byte initialization vector | 

All ContentKey elements in a single request must use the same `commonEncryptionScheme`. The response must include `cpix:Data/pskc:Secret/pskc:PlainValue` with a base64-encoded 16-byte AES key.

### DRMSystemList (mandatory)
<a name="speke-v2-drm-system-list"></a>

Contains one `DRMSystem` element per key per DRM system. Example: 2 keys x 3 DRM systems = 6 DRMSystem elements.


| Attribute | Required | Description | 
| --- | --- | --- | 
| kid | Yes | Key ID this DRM system applies to | 
| systemId | Yes | DRM system UUID | 

**Mandatory HLS signaling rules:**

1. All `HLSSignalingData` content must be base64-encoded.

1. Both `playlist="media"` and `playlist="master"` must be present.

1. Decoded media and master tags must have identical attributes. Only the tag name differs.

1. HLS tags must NOT contain a `SCHEME` attribute.

1. Each DRMSystem must reference exactly one `kid` with exactly one HLS tag.

### ContentKeyPeriodList (live streaming)
<a name="speke-v2-content-key-period-list"></a>

Must be echoed back unchanged from the request. MediaPackage sends this even without key rotation.

### ContentKeyUsageRuleList (mandatory)
<a name="speke-v2-usage-rule-list"></a>

Defines which keys protect which tracks. The AWS SPEKE v2 spec explicitly requires the key provider to echo back the ContentKeyUsageRuleList unchanged — MediaPackage defines the encryption contract (which keys protect which tracks), and the DRM server must not alter it.


| Attribute | Required | Description | 
| --- | --- | --- | 
| kid | Yes | Key ID this rule applies to | 
| intendedTrackType | Yes | ALL, VIDEO, AUDIO, SD, HD, UHD, etc. | 

At least one `VideoFilter` or `AudioFilter` child element is required.

## DRM system signaling
<a name="speke-v2-drm-signaling"></a>

**System IDs**


| System ID | Reference | Encryption Schemes | 
| --- | --- | --- | 
| 94ce86fb-07ff-4f43-adb8-93d2fa968ca2 | FairPlay | cbcs only | 
| edef8ba9-79d6-4ace-a3c8-27dcd51d21ed | Widevine | cenc, cbcs | 
| 9a04f079-9840-4286-ab92-e65be0885f95 | PlayReady | cenc, cbcs | 
| 3ea8778f-7742-4bf9-b18b-e834b2acbd47 | Clear Key AES-128 | cbc1 only | 

### FairPlay signaling
<a name="speke-v2-fairplay"></a>

**Response XML structure:**

```
<cpix:DRMSystem kid="8fe6f4de-..." systemId="94ce86fb-07ff-4f43-adb8-93d2fa968ca2">
  <cpix:HLSSignalingData playlist="media">BASE64_ENCODED_EXT_X_KEY</cpix:HLSSignalingData>
  <cpix:HLSSignalingData playlist="master">BASE64_ENCODED_EXT_X_SESSION_KEY</cpix:HLSSignalingData>
</cpix:DRMSystem>
```

FairPlay uses only HLS signaling (no PSSH or ContentProtectionData).

**Decoded HLS signaling (media and master identical except tag name):**

```
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="skd://<BASE64_JSON>",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
#EXT-X-SESSION-KEY:METHOD=SAMPLE-AES,URI="skd://<BASE64_JSON>",KEYFORMAT="com.apple.streamingkeydelivery",KEYFORMATVERSIONS="1"
```

The `skd://` URI contains a base64-encoded JSON payload — NOT just the kid hex:

```
{"ContentId":"101","KeyId":"8fe6f4de-841a-3acd-a81a-be516f356bbb","IV":"base64-encoded-IV=="}
```

**Important**  
The `KeyId` must use UUID format with hyphens. Do NOT include a separate `IV=0x...` attribute in the HLS tag — the IV is inside the JSON payload only.

### Widevine signaling
<a name="speke-v2-widevine"></a>

**Response XML structure:**

```
<cpix:DRMSystem kid="dda7afc9-..." systemId="edef8ba9-79d6-4ace-a3c8-27dcd51d21ed">
  <cpix:PSSH>BASE64_ENCODED_PSSH_BOX</cpix:PSSH>
  <cpix:ContentProtectionData>BASE64_ENCODED_CENC_PSSH_XML</cpix:ContentProtectionData>
  <cpix:HLSSignalingData playlist="media">BASE64_ENCODED_EXT_X_KEY</cpix:HLSSignalingData>
  <cpix:HLSSignalingData playlist="master">BASE64_ENCODED_EXT_X_SESSION_KEY</cpix:HLSSignalingData>
</cpix:DRMSystem>
```

Widevine includes PSSH box, ContentProtectionData, and HLS signaling. All values are base64-encoded.

**PSSH Box:** Base64-encoded binary data containing the Widevine PSSH box. The box structure is:

```
  [4 bytes] Box size (big-endian uint32)
  [4 bytes] Box type: "pssh"
  [1 byte]  Version: 0
  [3 bytes] Flags: 0
  [16 bytes] System ID: edef8ba9-79d6-4ace-a3c8-27dcd51d21ed (Widevine)
  [4 bytes] Data size (big-endian uint32)
  [N bytes] Widevine PSSH data (protobuf-encoded, contains key IDs and provider)
```

**ContentProtectionData (base64-decoded):** Must use the standard CENC PSSH XML format:

```
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">PSSH_BOX_BASE64</cenc:pssh>
```

The PSSH\$1BOX\$1BASE64 inside `cenc:pssh` is the same base64-encoded PSSH box as in the `cpix:PSSH` element.

**Decoded HLS signaling:** The URI must be a data URI with the PSSH box embedded inline:

```
#EXT-X-KEY:METHOD=SAMPLE-AES,URI="data:text/plain;base64,<PSSH_BOX_BASE64>",KEYFORMAT="urn:uuid:edef8ba9-79d6-4ace-a3c8-27dcd51d21ed",KEYFORMATVERSIONS="1"
```

**Important**  
The URI must be a `data:text/plain;base64,` data URI containing the PSSH box — NOT a license server URL (e.g., `https://widevine.example.com/license`). ContentProtectionData must use the `cenc:pssh` format — NOT custom wrappers like `<ContentProtectionData><PSSH>...</PSSH></ContentProtectionData>`. Do NOT include a `SCHEME` attribute in HLS tags.

### PlayReady signaling
<a name="speke-v2-playready"></a>

**Response XML structure:**

```
<cpix:DRMSystem kid="566209fc-..." systemId="9a04f079-9840-4286-ab92-e65be0885f95">
  <cpix:PSSH>BASE64_ENCODED_PSSH_BOX</cpix:PSSH>
  <cpix:ContentProtectionData>BASE64_ENCODED_CENC_PSSH_AND_MSPR_PRO</cpix:ContentProtectionData>
  <cpix:HLSSignalingData playlist="media">BASE64_ENCODED_EXT_X_KEY</cpix:HLSSignalingData>
  <cpix:HLSSignalingData playlist="master">BASE64_ENCODED_EXT_X_SESSION_KEY</cpix:HLSSignalingData>
</cpix:DRMSystem>
```

PlayReady includes PSSH box, ContentProtectionData (with both CENC and PRO elements), and HLS signaling.

**PSSH Box:** Base64-encoded binary data containing the PlayReady PSSH box. The box structure is:

```
  [4 bytes] Box size (big-endian uint32)
  [4 bytes] Box type: "pssh"
  [1 byte]  Version: 0
  [3 bytes] Flags: 0
  [16 bytes] System ID: 9a04f079-9840-4286-ab92-e65be0885f95 (PlayReady)
  [4 bytes] Data size (big-endian uint32)
  PlayReady Object (PRO) record:
    [4 bytes] Record count (little-endian uint32, always 1)
    [4 bytes] Record size (little-endian uint32)
    [N bytes] WRM Header XML (UTF-16LE encoded)
```

The WRM Header XML contains `KID`, `CHECKSUM`, `LA_URL` (license acquisition URL), `ALGID`, and `KEYLEN` elements for each content key.

**ContentProtectionData (base64-decoded):** Must contain BOTH `cenc:pssh` AND `mspr:pro` elements:

```
<cenc:pssh xmlns:cenc="urn:mpeg:cenc:2013">PSSH_BASE64</cenc:pssh>
<mspr:pro xmlns:mspr="urn:microsoft:playready">PRO_RECORD_BASE64</mspr:pro>
```

The `cenc:pssh` contains the full PSSH box. The `mspr:pro` contains the PlayReady Object record (count \$1 size \$1 WRM Header XML in UTF-16LE).

**Decoded HLS signaling (attribute order: METHOD, KEYFORMAT, KEYFORMATVERSIONS, URI):** The data URI must use `charset=UTF-16` and contain the PlayReady Object record (PRO), NOT the raw PSSH box:

```
#EXT-X-KEY:METHOD=SAMPLE-AES,KEYFORMAT="com.microsoft.playready",KEYFORMATVERSIONS="1",URI="data:text/plain;charset=UTF-16;base64,<PRO_RECORD_BASE64>"
```

**Important**  
The data URI must use `charset=UTF-16` and embed the PlayReady Object record, NOT the raw PSSH box. The PRO record structure: count(4 bytes LE) \$1 size(4 bytes LE) \$1 WRM Header XML (UTF-16LE). Attribute order must be METHOD, KEYFORMAT, KEYFORMATVERSIONS, URI. ContentProtectionData must include BOTH `cenc:pssh` AND `mspr:pro`. Omitting either will cause failures. Do NOT include a `SCHEME` attribute.

### Clear Key AES-128 signaling
<a name="speke-v2-clearkey-aes128"></a>

**Response XML structure:**

```
<cpix:DRMSystem kid="136436ea-..." systemId="3ea8778f-7742-4bf9-b18b-e834b2acbd47">
  <cpix:HLSSignalingData playlist="media">BASE64_ENCODED_EXT_X_KEY</cpix:HLSSignalingData>
  <cpix:HLSSignalingData playlist="master">BASE64_ENCODED_EXT_X_SESSION_KEY</cpix:HLSSignalingData>
</cpix:DRMSystem>
```

Clear Key AES-128 uses only HLS signaling (no PSSH or ContentProtectionData).

**Decoded HLS signaling:**

```
#EXT-X-KEY:METHOD=AES-128,URI="https://<key_server>/client/<content_id>/<kid>",KEYFORMAT="identity",KEYFORMATVERSIONS="1"
```

The key delivery endpoint must return the raw 16-byte binary key (not base64) with CORS headers. No DRM license server is needed — the player fetches the key directly.

## Key delivery to players
<a name="speke-v2-key-delivery"></a>


| DRM System | Player-side key delivery | License server required | 
| --- | --- | --- | 
| Clear Key AES-128 | Player GETs raw 16-byte key from HTTPS URL in manifest | No | 
| FairPlay | Player contacts FPS license server using skd:// URI | Yes (Apple FPS license) | 
| Widevine | Player uses EME API with PSSH from data URI | Yes (Google/3rd party) | 
| PlayReady | Player uses EME API with PRO from data URI | Yes (Microsoft/3rd party) | 

## Testing and verification
<a name="speke-v2-testing"></a>

**Verify your SPEKE v2.0 implementation**

1. **Test SPEKE endpoint directly.** Send a POST request with a CPIX XML body and verify the response contains `contentId`, `version="2.3"`, `PlainValue` with 16-byte base64 key, `explicitIV`, base64-encoded HLSSignalingData, and echoed ContentKeyPeriodList.

1. **Verify key determinism.** Send the same request twice. The `PlainValue` should be identical both times.

1. **Verify HLS signaling.** Decode the base64 HLSSignalingData and verify: FairPlay uses `skd://` with JSON payload, Widevine uses `data:text/plain;base64,` with PSSH, PlayReady uses `data:text/plain;charset=UTF-16;base64,` with PRO, no SCHEME attribute, media and master tags match.

1. **Test with MediaPackage.** Configure a MediaPackage endpoint with SPEKE encryption, start a live stream, check server logs for requests, and verify playback.

## Implementation checklist
<a name="speke-v2-checklist"></a>
+ HTTP endpoint accepts POST with `Content-Type: application/xml`
+ Validates and echoes `X-Speke-Version` header
+ Returns `X-Speke-User-Agent` response header
+ Validates `contentId`, `version`, `commonEncryptionScheme`
+ Returns HTTP 422 with exact error messages per SPEKE specification
+ Generates deterministic 16-byte AES keys with `explicitIV`
+ Generates per-kid DRMSystem elements
+ Base64-encodes all HLSSignalingData, PSSH, and ContentProtectionData
+ FairPlay: `skd://` URI contains base64-encoded JSON with ContentId, KeyId (with hyphens), and IV
+ Widevine: HLS URI uses `data:text/plain;base64,<PSSH>`; ContentProtectionData uses `cenc:pssh`
+ PlayReady: HLS URI uses `data:text/plain;charset=UTF-16;base64,<PRO>`; ContentProtectionData includes both `cenc:pssh` and `mspr:pro`; attribute order METHOD, KEYFORMAT, KEYFORMATVERSIONS, URI
+ Clear Key AES-128: provides GET endpoint returning raw 16-byte key with CORS headers
+ HLS media and master tags have identical attributes; no SCHEME attribute
+ Echoes ContentKeyPeriodList and ContentKeyUsageRuleList unchanged
+ Includes VideoFilter and/or AudioFilter in usage rules

# Preparing and managing certificates for content key encryption
<a name="drm-content-key-encryption"></a>

When implementing DRM encryption, AWS Elemental MediaPackage can enhance security by encrypting the content keys within the Content Protection Information Exchange (CPIX) document exchanged with your key provider. This additional encryption layer protects the content keys during transmission between MediaPackage and your DRM key provider.

## Overview
<a name="content-key-encryption-overview"></a>

When you create or modify origin endpoint resources in MediaPackage for DRM-protected content, you can optionally specify a certificate ARN in the SPEKE encryption settings. This certificate ARN must point to a certificate stored in AWS Certificate Manager (ACM). This certificate provides encryption for content keys delivery between MediaPackage and your key provider, as described in the [SPEKE Version 2.0 content key encryption](https://docs.aws.amazon.com/speke/latest/documentation/content-key-encryption-v2.html) specification.

This is an opt-in configuration. When you don't provide a certificate in your origin endpoint resource's SPEKE encryption configuration, DRM key providers return content keys as plain text, which is the current and default behavior. When you provide a certificate, the content key returned by your DRM key provider is encrypted using the certificate's public key, and MediaPackage decrypts the encrypted content key with the certificate's private key.

To use encrypted content keys, the following requirements must be met:
+ Your DRM key provider must support content key encryption. If you enable this feature for a key provider that doesn't handle content key encryption, playback fails.
+ You must provide a certificate stored in AWS Certificate Manager (ACM) in the same Region and Account that you run MediaPackage. For information about ACM, see the [AWS Certificate Manager User Guide](https://docs.aws.amazon.com/acm/latest/userguide/).

  When you create or update an origin endpoint resource with certificate ARN, you must have ACM permissions.

  The certificate must meet the following requirements:
  + **Status**: The certificate must be in **ISSUED** status
  + **Domain name**: The certificate must have a domain name
  + **Key algorithm**: The certificate must use RSA-2048 key algorithm
  + **Signature algorithm**: The certificate must use either SHA-256 or SHA-512 signature algorithm
  + **Region**: The certificate must be in the same AWS Region as your origin endpoint
  + **Account**: The certificate must be in the same AWS Account as your origin endpoint
+ The origin endpoint ARN length must not exceed 222 characters. An origin endpoint ARN follows this format: `arn:aws:mediapackagev2:region:123456789012:channelGroup/channelGroupName/channel/channelName/originEndpoint/originEndpointName`. If the ARN length exceeds this limit, origin endpoint creation with content key encryption will fail due to an ARN length restriction.

  The following procedures describe how to prepare and manage the certificate.

**To prepare a certificate for DRM content key encryption**

1. Open the ACM console at [https://console.aws.amazon.com/acm/](https://console.aws.amazon.com/acm/).

1. Import or request a certificate into ACM according to the instructions at [AWS Certificate Manager User Guide](https://docs.aws.amazon.com/acm/latest/userguide/). Note the resulting certificate ARN because you will need it later.

   For use in DRM encryption, your certificate must have a status of **Issued** in ACM.

**To use a certificate in MediaPackage**

When you create or modify an origin endpoint with DRM encryption, provide your certificate ARN in the SPEKE encryption parameters. This enables content key encryption. You can use the same certificate ARN for multiple origin endpoints. For information, see the encryption settings information in [Working with origin endpoints in AWS Elemental MediaPackage](endpoints.md).

## How content key encryption works
<a name="how-content-key-encryption-works"></a>

When you configure certificate-based content key encryption, the following process occurs:

1. **MediaPackage retrieves your certificate**: MediaPackage uses your certificate ARN to retrieve the certificate details from ACM.

1. **CPIX request with certificate**: MediaPackage includes your certificate's public key in the CPIX request sent to your DRM key provider.

1. **DRM provider encrypts keys**: Your DRM key provider uses the certificate's public key for content key encryption

1. **MediaPackage decrypts keys**: MediaPackage uses the certificate's private key for content key decryption

1. **Content encryption**: MediaPackage uses the decrypted content keys to encrypt your content

**Note**  
This process follows the [SPEKE Version 2.0 content key encryption](https://docs.aws.amazon.com/speke/latest/documentation/content-key-encryption-v2.html) specification for secure key exchange. Content key encryption adds an additional layer of security to the delivery of content key without affecting the final content encryption.

**To delete a certificate**

To delete a certificate from ACM, it must not be associated with any other resources. Delete the certificate ARN from origin endpoint configurations where you have used it, then delete it from ACM. 

**Note**  
If you delete a certificate ARN from an active origin endpoint, the endpoint keeps running, but stops using content key encryption. 

# AWS Elemental MediaPackage key rotation behavior
<a name="drm-content-key-rotation"></a>

When you enable key rotation on live content from TS and CMAF origin endpoints, AWS Elemental MediaPackage retrieves content keys before the live content begins. As the content progresses, MediaPackage retrieves new keys at the interval that you set on the origin endpoint, as described in [Encryption fields](endpoints-create.md#endpoints-encryption).

If MediaPackage is unable to retrieve the content key, it takes the following actions:
+ If MediaPackage successfully retrieved a content key for this endpoint before, it uses the last key that it fetched. This ensures that endpoints that worked previously continue to work. 
+ If MediaPackage has *not* successfully retrieved a content key for this endpoint before, MediaPackage responds to the playback request with error 404. 

# Managing DRM segment metadata in AWS Elemental MediaPackage
<a name="drm-segment-metadata-management"></a>

AWS Elemental MediaPackage includes DRM segment metadata boxes (SEIG and SGPD) in CMAF container segments by default. These boxes contain key rotation metadata that helps players manage DRM key changes during playback. However, some devices and players don't support these metadata boxes, which can cause compatibility issues.

## Overview of SEIG and SGPD boxes
<a name="drm-segment-metadata-overview"></a>

DRM segment metadata boxes serve specific functions in encrypted content delivery:
+ **SEIG (Sample Encryption Information Group) boxes** - Contain sample-level encryption information including initialization vectors and subsample encryption patterns.
+ **SGPD (Sample Group Description) boxes** - Define the structure and parameters for sample groups, including encryption-related groupings.

These boxes work together to provide detailed encryption metadata at the segment level, enabling fine-grained control over DRM key rotation and sample encryption patterns.

## Device compatibility challenges
<a name="drm-segment-metadata-compatibility"></a>

While SEIG and SGPD boxes provide valuable functionality, they can cause compatibility issues with certain devices and players:
+ **MatchPoint and FairPlay devices** - Some devices that use MatchPoint or FairPlay DRM systems may not properly parse or handle these metadata boxes, leading to playback failures.
+ **MP browser implementations** - Certain browser-based media players may encounter parsing errors when processing segments with these metadata boxes.
+ **Vuze devices** - Some Vuze-based players may not support the additional metadata complexity, resulting in compatibility issues.
+ **Legacy FairPlay implementations** - Older FairPlay implementations may not handle the metadata boxes correctly, particularly in combination with other DRM features.

When these compatibility issues occur, players may fail to start playback, encounter buffering problems, or display error messages related to DRM or segment parsing.

## When to exclude segment metadata
<a name="drm-segment-metadata-when-to-exclude"></a>

Consider excluding DRM segment metadata in the following scenarios:
+ **Device compatibility requirements** - When your content must play on devices known to have issues with SEIG and SGPD boxes.
+ **Simplified DRM workflows** - When you can handle key rotation through media playlist signaling instead of segment-level metadata.
+ **Legacy player support** - When supporting older players that don't implement full support for these metadata boxes.
+ **Troubleshooting playback issues** - As a diagnostic step when investigating DRM-related playback problems.

**Note**  
Excluding segment metadata doesn't affect other DRM functionality. PSSH (Protection System Specific Header) and TENC (Track Encryption) boxes remain unaffected and continue to provide essential DRM information.

## Alternative key rotation methods
<a name="drm-segment-metadata-alternative-key-rotation"></a>

When you exclude segment metadata, key rotation can still be handled through alternative methods:
+ **Media playlist signaling** - Key rotation information can be communicated through HLS media playlists using EXT-X-KEY tags or DASH manifests using ContentProtection elements.
+ **Manifest-level metadata** - DRM key information can be provided at the manifest level rather than within individual segments.
+ **Player-side key management** - Players can manage key rotation based on timing information and DRM license responses rather than segment metadata.

These alternative methods ensure that DRM functionality remains intact while improving compatibility with devices that don't support segment-level metadata boxes.

## Configuration requirements
<a name="drm-segment-metadata-configuration"></a>

The segment metadata exclusion feature has specific requirements and limitations:
+ **Container format requirement** - This setting only affects CMAF container formats. TS (Transport Stream) containers don't include SEIG and SGPD boxes, so this setting doesn't apply.
+ **Encryption requirement** - The setting is only available when DRM encryption is enabled on the origin endpoint.
+ **Default behavior** - By default, MediaPackage includes segment metadata boxes. You must explicitly enable the exclusion setting to omit them.
+ **Existing endpoints** - Existing origin endpoints that don't have this setting configured will continue to include segment metadata boxes (default behavior).

To configure this setting using the MediaPackage console, see [Encryption fields](endpoints-create.md#endpoints-encryption).

# Excluding DRM session keys in AWS Elemental MediaPackage
<a name="drm-session-key-exclusion"></a>

MediaPackage supports excluding session keys from HLS and LL-HLS multivariant playlists to improve compatibility with legacy clients and provide more granular access control.

## Overview
<a name="drm-session-key-exclusion-overview"></a>

By default, MediaPackage includes `EXT-X-SESSION-KEY` tags in HLS multivariant playlists when DRM is enabled. These tags allow clients to pre-fetch encryption keys, which can improve playback performance. However, some scenarios require excluding these session keys:
+ **Legacy client compatibility** - Some older HLS clients have issues processing session keys and may fail to play content when these tags are present.
+ **Access control** - When using manifest filtering to control access to specific content variants, you may want to provide key information only for the streams a client actually has access to, rather than exposing all keys in the session key tags.

When session keys are excluded, encryption key information is still available in the individual media playlists through `EXT-X-KEY` tags, ensuring that DRM functionality remains intact.

## Configuration options
<a name="drm-session-key-exclusion-configuration"></a>

You can exclude session keys using two methods:
+ **Static configuration** - Configure the setting on the origin endpoint HLS or LL-HLS manifests to exclude session keys. This is done through the **DRM settings** in the filter configuration. For console instructions, see [Manifest fields](endpoints-create.md#endpoints-manifest).
+ **Dynamic exclusion** - Use the `aws.drmsettings=exclude_session_keys` query parameter to exclude session keys on a per-request basis. For more information, see [Manifest filtering](manifest-filtering.md).

**Note**  
If session key exclusion is enabled in the static configuration, it cannot be overridden using query parameters. This follows the standard MediaPackage pattern where static filters take precedence over dynamic parameters.

# Encryption presets in AWS Elemental MediaPackage
<a name="drm-content-speke-v2-presets"></a>

SPEKE Version 2.0 supports the use of multiple, distinct encryption keys for audio and video tracks. MediaPackage uses **presets** to configure the encryption. The MediaPackage API defines these presets, and they appear in the MediaPackage console in the **Video encryption preset** and **Audio encryption preset** menus of the **Package Encryption endpoints configuration** section. The presets map encryption keys to specific audio or video tracks, based on the number of channels for audio tracks, and based on the video resolution for video tracks. MediaPackage uses specific combinations of audio and video encryption presets to support three different encryption scenarios:
+ [Scenario 1: Unencrypted tracks and encrypted tracks](#drm-content-speke-v2-presets-unencrypted-and-encrypted-tracks)
+ [Scenario 2: Single encryption key for all audio and video tracks](#drm-content-speke-v2-presets-single-encryption-key-for-all-tracks)
+ [Scenario 3: Multiple encryption keys for audio and video tracks](#drm-content-speke-v2-presets-multiple-encryption-keys-for-audio-and-video-tracks)

## Scenario 1: Unencrypted tracks and encrypted tracks
<a name="drm-content-speke-v2-presets-unencrypted-and-encrypted-tracks"></a>

You can choose *not* to encrypt the audio or the video tracks by selecting the **UNENCRYPTED** preset in the **Video encryption preset** or the **Audio encryption preset** menus. You can’t select **UNENCRYPTED** for both audio and video presets, because doing so would mean that you don’t intend to encrypt any of the tracks at all. Also, you can’t combine **UNENCRYPTED** and **SHARED** presets for audio and video, because **SHARED** is a special preset. For more information, see [Scenario 2: Single encryption key for all audio and video tracks](#drm-content-speke-v2-presets-single-encryption-key-for-all-tracks). 

The following list describes valid combinations of **UNENCRYPTED** presets:
+ **UNENCRYPTED** for audio tracks, and any video preset with a name that starts with `PRESET-VIDEO-`
+ **UNENCRYPTED** for video tracks, and any audio preset with a name that starts with `PRESET-AUDIO-`

## Scenario 2: Single encryption key for all audio and video tracks
<a name="drm-content-speke-v2-presets-single-encryption-key-for-all-tracks"></a>

The SPEKE Version 2.0 **SHARED** preset uses a single encryption key for all audio and video tracks, as in SPEKE Version 1.0. When you select the **SHARED** preset, select it for both audio and video encryption.

## Scenario 3: Multiple encryption keys for audio and video tracks
<a name="drm-content-speke-v2-presets-multiple-encryption-keys-for-audio-and-video-tracks"></a>

When you use a preset with a name that starts with `PRESET-VIDEO-` or `PRESET-AUDIO-`, MediaPackage encrypts the audio tracks and video tracks with the number of encryption keys that the specific preset defines. The following tables show how many keys MediaPackage requests from the key server and how those keys map to tracks. If no track matches the criteria for a particular key, MediaPackage does not use that key to encrypt any track.

MediaPackage encrypts I-frame only trickplay tracks with the key corresponding to their resolution. 

In the following table, the **Key name** value is the value of the `ContentKeyUsageRule@IntendedTrackType` attribute that MediaPackage uses in the CPIX document. This is sent to the SPEKE server for a specific content key.


**Video encryption presets**  
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/mediapackage/latest/userguide/drm-content-speke-v2-presets.html)

In the following table, the **Key name** value is the value of the `ContentKeyUsageRule@IntendedTrackType` attribute that MediaPackage uses in the CPIX document. This is sent to the SPEKE server for a specific content key.


**Audio encryption presets**  
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/mediapackage/latest/userguide/drm-content-speke-v2-presets.html)

Now you know how MediaPackage supports SPEKE Version 2.0 presets for unencrypted tracks and encrypted tracks. With these presets, you can use a single encryption key for all audio and video tracks, and multiple encryption keys for audio and video tracks. 