# Guide to Enabling Authentication for ClearKey-Encrypted Videos

Protecting video content from unauthorized access is critically important, especially for streaming providers who need to preserve content value and prevent piracy.

ClearKey is a DRM system that is less complex than Widevine or FairPlay, yet still provides adequate basic protection.

This document describes the weaknesses of the existing ClearKey system and the approach to adding an authentication mechanism to strengthen overall security.


# Overview of the Existing ClearKey System

# Basic Operating Principles

ByteArk Stream supports processing ClearKey-encrypted videos using the AES-128 algorithm for HLS (HTTP Live Streaming) format videos. Viewers cannot watch encrypted videos without first obtaining the encryption key for decryption, even if they manage to download the video by any means.

# HLS Structure and Encryption

In the HLS format, video is divided into smaller pieces called "Segments," and the Manifest file contains references to the location of the decryption key.

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:10
#EXT-X-KEY:METHOD=AES-128,URI="https://key-server.example.com/key",IV=0x...
#EXTINF:10.0,
segment1.ts
#EXTINF:10.0,
segment2.ts
1
2
3
4
5
6
7
8

In the example above, #EXT-X-KEY indicates that the video is encrypted with AES-128 and the key can be requested from the specified URL.


# Weaknesses of the Current System

# Lack of Authentication Mechanism

Although the ClearKey system provides basic protection through encryption, it has a critical weakness: key requests have no access control verification.

# Issues

  1. Unauthorized key access - Malicious actors can directly request the decryption key if they know the URL.
  2. Key sharing - Authorized users can share the key with others.
  3. Lack of access control - It is not possible to restrict access by duration, number of uses, or revoke access.

# Sequence Diagram: Legacy System

# ClearKey Legacy System Workflow

# Legacy System Workflow Explanation

# Step 1: Manifest Fetch

The viewer requests the Manifest file from the Manifest Server to receive information about the video they want to watch.

# Step 2: Key Fetch (Main Weakness)

This is the critical weakness of the system. The key is sent immediately without verifying whether the requester is an authorized user.

# Step 3: Video Playback

After receiving the key, the viewer can decrypt and play the video immediately.


# Sequence Diagram: New System with Authentication

# Approach to Fixing the Weaknesses

To address the weaknesses described above, ByteArk has developed a new system that adds an authentication mechanism to the core process, based on the following key principles:

  1. Key Pair Generation: Create a public/private key pair for digital signing.
  2. Authentication: Verify user permissions before granting access to content.
  3. Session Management: Control access duration and scope.
  4. Domain Verification: Restrict access to authorized sources only.

# New System Sequence Diagram

# New System Workflow Explanation

# Step 1: Setup Key Pair

In this step, the customer creates a Key Pair for authentication:

  1. Send a request to create a Key Pair to the Stream API along with a PAT and Playback Channel ID.
  2. Receive the Private Key and Keypair ID in return.
  3. Store the Private Key securely for signing JWT Tokens.

# Step 2: Authentication

This step is the core of the new system, verifying user permissions before granting access to content:

  1. The viewer sends an authentication request to the customer's Backend (using OAuth, Username/Password, or other methods as defined by the customer).
  2. The Backend verifies the user information and creates a JWT Token signed with the Private Key.
  3. The viewer sends the JWT Token to the Key Server via the SDK using the initAuth() function.
  4. If valid, the viewer receives a Session and Refresh Token.

# Step 3: Manifest Fetch

After successful authentication, the viewer can request video information:

  1. Request the Playlist file from the Manifest Server.
  2. Receive the Playlist back with the Key Server URL.
  3. Request prog_index.m3u8 specifying x_ark_origin (or using the default value).

# Step 4: Key Fetch

In the final step, the viewer can request the decryption key:

  1. Send a request to the Key Server with the attached Session.
  2. Receive the decryption key in return.
  3. When the Session is about to expire, call renewSession() to renew it.

# Passport Key Server APIs

# Authentication and Authorization

All endpoints require the following Request Headers:

Header Value Required Description
Authorization Bearer <access_token> Yes Access token of the authenticated user
x-byteark-team <team_identifier> Yes Team identifier of the caller

# 1. Create Key Pair for Playback Channel

Create an ECDSA key pair for a Playback Channel to use for authentication.

# Endpoint

POST /playback-channels/:playbackChannelId/key-pair
1

# Path Parameters

Parameter Type Required Description
passportKeyServerId string Yes Passport Key Server ID

# Request Body

Content-Type: application/json

Field Type Required Description
enabledCookieAuth boolean Yes Enable (true) or disable (false) Cookie Authentication

# Example

{
  "enabledCookieAuth": true
}
1
2
3

# Response

# 200 OK

Field Type Description
id string Record ID
playbackChannelId string Playback Channel ID
allowDomains string[] List of allowed domains
defaultDomain string Default domain
passportClearKeyServerId string Passport Clear Key Server ID
enabledCookieAuth boolean Current Cookie Authentication status

# Example

{
  "id": "65a1b2c3d4e5f67890abcdef",
  "playbackChannelId": "pc-abc123",
  "allowDomains": ["example.com", "cdn.example.com"],
  "defaultDomain": "example.com",
  "passportClearKeyServerId": "pcks-def456",
  "enabledCookieAuth": true
}
1
2
3
4
5
6
7
8

# 3. Update Allowed Domains

Update the list of allowed domains for the specified Passport Key Server.

# Endpoint

PUT /passport-keyservers/:passportKeyServerId/allow-domains
1

# Path Parameters

Parameter Type Required Description
passportKeyServerId string Yes Passport Key Server ID

# Request Body

Content-Type: application/json

Field Type Required Description
allowDomains string[] Yes List of allowed domains

# Example

{
  "allowDomains": ["example.com", "cdn.example.com"]
}
1
2
3

# Response

# 200 OK

Field Type Description
id string Record ID
defaultDomain string Default domain
allowDomains string[] List of allowed domains (updated)
enabledCookieAuth boolean Current Cookie Authentication status

# Example

{
  "id": "65a1b2c3d4e5f67890abcdef",
  "defaultDomain": "example.com",
  "allowDomains": ["example.com", "cdn.example.com"],
  "enabledCookieAuth": true
}
1
2
3
4
5
6

# 4. Revoke/Unrevoke Key Pair

Revoke or restore the usage of a Key Pair on the Passport Key Server.

# Endpoint

PUT /passport-keyservers/key-pairs/:keyPairId/revoked
1

# Path Parameters

Parameter Type Required Description
keyPairId string Yes Key Pair ID

# Request Body

Content-Type: application/json

Field Type Required Description
revoked boolean Yes Revoke (true) or unrevoke (false) the Key Pair

# Example

{
  "revoked": true
}
1
2
3

# Response

# 200 OK

Field Type Description
keyPairId string Key Pair ID
revoked boolean Current revocation status

# Example

{
  "keyPairId": "65a1b2c3d4e5f67890abcdef",
  "revoked": true
}
1
2
3
4

# 404 Not Found

Returned when the specified Key Pair is not found.

Field Type Description
message string Error message

# Domain Configuration Requirements for API Sessions

[!IMPORTANT] To use API Sessions (Cookie-based Authentication), the Key Server domain and the Client domain must be under the same Top-Level Domain.

# Why Domain Configuration Must Match

The session system uses an HTTP Cookie (session_token) to store the token. The cookie domain is set to the root domain of the Key Server, for example:

Key Server Hostname Cookie Domain Set
api.example.com .example.com
key-server.byteark.com .byteark.com
localhost localhost

Since browsers only send cookies back to servers with matching domains, if the Client is on a different Top-Level Domain from the Key Server, the cookie will not be sent, rendering the session unusable.

# Examples

# Works (Matching Domains)

Key Server:  https://api.example.com
Client App:  https://player.example.com
→ Cookie Domain = .example.com → Shared successfully
1
2
3

# Does Not Work (Mismatched Domains)

Key Server:  https://api.example.com
Client App:  https://player.another-site.com
→ Cookie Domain = .example.com → Browser does not send cookie to another-site.com
1
2
3

# Solution

If the Client domain does not match the Key Server, create an Alias (CNAME) for the Key Server domain under the same domain as the Client, for example:

Client App:     https://player.mysite.com
Key Server:     https://api.example.com
→ Create CNAME: key-server.mysite.com → api.example.com
→ Call API via: https://key-server.mysite.com
→ Cookie Domain = .mysite.com → Shared successfully
1
2
3
4
5
6

[!WARNING] If you do not create a domain alias, the session system will not work because the browser will not send cookies across domains, and all API calls requiring a session will receive HTTP 401 Unauthorized every time.

# Summary

Action Required Details
Verify domains Ensure the Client and Key Server are under the same Top-Level Domain
Create CNAME (if needed) Alias the Key Server domain under the Client's domain
Configure SSL Ensure the aliased domain has a valid SSL Certificate
Test cookies Verify that the session_token cookie is sent correctly with requests