# JWT Token Authentication

When a content key policy uses token restriction, the player must include a valid JWT token in the license acquisition request. MK.IO validates the token against the issuer, audience, and primary verification key configured in the policy before issuing a decryption license.

## How JWT tokens work with DRM

The token acts as proof that the viewer is authorized to access the content. The flow works as follows:

1. Your application generates a JWT token using the same signing key configured in the content key policy.
2. The player includes the token as an `Authorization` header in the license request.
3. MK.IO validates the token signature, issuer, and audience.
4. If valid, MK.IO returns the decryption license. If invalid, the request is rejected.

## Required and optional claims

The JWT token payload must include certain claims that match the content key policy configuration.

| Claim                                                    | Required | Description                                                                                                                                 |
| -------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `iss`                                                    | Yes      | The issuer value. Must match the **Issuer** field in the content key policy.                                                                |
| `aud`                                                    | Yes      | The audience value. Must match the **Audience** field in the content key policy.                                                            |
| `exp`                                                    | No       | Token expiry time as a Unix epoch timestamp in seconds. The token cannot be used after this time.                                           |
| `nbf`                                                    | No       | "Not before" time as a Unix epoch timestamp in seconds. The token cannot be used before this time.                                          |
| `urn:microsoft:azure:mediaservices:contentkeyidentifier` | No       | The streaming locator content key ID. Use this claim to bind the token to a specific locator. The value is available through the MK.IO API. |

## Generate a JWT token

### Gather your policy values

Retrieve the following values from the content key policy you created:

- **Issuer**: the string you entered in the issuer field.
- **Audience**: the string you entered in the audience field.
- **Primary verification key**: the Base64-encoded key you entered.

### Build the token payload

Construct the JWT payload with the required claims:

```json
{
  "iss": "<your-issuer>",
  "aud": "<your-audience>"
}
```

To add an expiry, include the `exp` and optionally `nbf` claims:

```json
{
  "iss": "<your-issuer>",
  "aud": "<your-audience>",
  "nbf": 1707942000,
  "exp": 1707942300
}
```

The `nbf` and `exp` values are Unix epoch timestamps in seconds. Do not wrap them in quotes.

### Sign the token

Use a JWT generation tool such as [jwt.io](https://jwt.io) to sign the token:

1. In the **PAYLOAD** section, enter your claims JSON.
2. In the **VERIFY SIGNATURE** section, paste your **primary verification key** in the secret field.
3. Check the **secret base64 encoded** checkbox.
4. The **Encoded** panel on the left displays the signed JWT token.

The algorithm must be `HS256` (HMAC with SHA-256), which is the default.

### Use the token in playback

Include the JWT token in the license request headers when configuring your player:

```json
{"Authorization": "Bearer <your-jwt-token>"}
```

In MKPlayer, paste this value in the **License request headers** field. In the MKPlayer SDK, pass it in the `headers` object of the DRM configuration. See [Test DRM playback](/mkio/how-to/drm-content-protection/test-drm-playback) for details.

## Example

The following example shows a complete JWT configuration:

**Content key policy settings:**

| Field                    | Value                      |
| ------------------------ | -------------------------- |
| Issuer                   | `mycompany`                |
| Audience                 | `myaudience`               |
| Primary verification key | `bXljb21wYW55YXVkaWVuY2U=` |

**JWT payload:**

```json
{
  "iss": "mycompany",
  "aud": "myaudience",
  "nbf": 1707942000,
  "exp": 1707942300
}
```

**Signing secret:** `bXljb21wYW55YXVkaWVuY2U=` (with **secret base64 encoded** checked).

The resulting encoded token is used as the `Bearer` value in the `Authorization` header.

## Programmatic token generation

For production use, generate JWT tokens server-side rather than using jwt.io. Any JWT library that supports HS256 signing can produce valid tokens. Decode the Base64 primary verification key and use it as the HMAC secret.

> **Warning:** Never expose the primary verification key in client-side code. Generate tokens on your server and pass them to the player at runtime.
