> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://fastpix.com/docs/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://fastpix.com/docs/_mcp/server.

# Video security overview

> Understand FastPix video security: private media with JWT tokens, domain and user-agent restrictions, DRM, how JWT tokens work, and what is and is not protected.

FastPix video security does two different jobs. Access control decides who can start playback and from where, and content protection decides what a viewer can do with the video once it is playing. It helps to keep the two separate.

Layered together, a private policy, a JWT token, and DRM shut the door on the overwhelming majority of unauthorized access and casual copying. No system is absolute, but combining them raises the bar high enough that hotlinking, link sharing, and downloading all stop being easy.

\


## The two layers

* **Access control (who can play):** private media played with a JWT token, plus optional domain and user-agent restrictions. These decide whether playback can begin. They do not change the video or stop a viewer from recording it once it plays.
* **Content protection (what they can do with it):** DRM encrypts the video so it only plays inside a protected player. On supporting devices, it will block screenshots and screen recording.

Many setups use both: DRM for the content, and a JWT token to authorize each viewer.

\


## Where security lives: your app and FastPix

Video security is a shared job between your app and FastPix:

* **Your app (the app layer):** you decide who is allowed to watch. Your app handles sign-in, subscriptions, and paywalls, and your server signs a JWT token only for viewers who pass those checks.
* **FastPix (player layer):** FastPix enforces what your app decided. It checks the JWT token, applies the access policy and any domain or user-agent rules, and encrypts the video with DRM.

In short, your app decides who gets in, and FastPix makes sure only those viewers can actually play the video.

\


## What each mechanism does

| Mechanism                               | What it does                                                                                                                                                                                                         | What it does not do                                                                                                                                   |
| --------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Private media (JWT token)**           | The video plays only if the viewer has a valid JWT token. If the token is missing, expired, or changed, playback is blocked. The same token also unlocks the video's thumbnail and preview images (the spritesheet). | Controls who can play, but does not encrypt the video. Only DRM does that. An approved viewer can still record their screen.                          |
| **Domain restrictions**                 | Allow or deny which websites can play the video (up to 25 entries, with `*.example.com` wildcards).                                                                                                                  | Relies on the browser-reported origin, and does not stop recording.                                                                                   |
| **User-agent restrictions**             | Allow or deny players and apps by User-Agent string (up to 25 entries, exact match).                                                                                                                                 | The User-Agent can be spoofed, so use it as a filter, not as real access control.                                                                     |
| **DRM (Widevine, PlayReady, FairPlay)** | Encrypts the video and delivers the key per session. On supporting devices, blocks screenshots and recording.                                                                                                        | Works for video on demand only, not live. It is off by default, so [reach out to FastPix](https://fastpix.com/contact) to enable it for your account. |

These mechanisms are designed to work together, so combining them, for example a private policy with a JWT token, domain and user-agent rules, and DRM, gives your content much stronger, layered protection.

\


## Access policies

Every asset has an access policy, set when you create it:

* **`public`:** anyone with the URL can play it.
* **`private`:** playback needs a valid JWT token.
* **`drm`:** playback is DRM-protected and also needs a valid JWT token (video on demand only).

| Capability                                             | Public | Private | DRM |
| ------------------------------------------------------ | :----: | :-----: | :-: |
| Plays with just the URL                                |    ✅   |    ❌    |  ❌  |
| Needs a JWT token                                      |    ❌   |    ✅    |  ✅  |
| Video is encrypted                                     |    ❌   |    ❌    |  ✅  |
| Can block screenshots and recording (device-dependent) |    ❌   |    ❌    |  ✅  |
| Works for live streams                                 |    ✅   |    ✅    |  ❌  |

You set the access policy when you create the asset or its playback ID. It cannot be changed afterward. To change access, create a new playback ID with the policy you want and delete the old one.

\


## Domain and user-agent restrictions

A **domain restriction** controls which websites can play the video. FastPix matches the site the player is embedded on against an allow or deny list, so you can let the video play only on your own domains (for example `example.com` and `*.example.com`) and block hotlinking elsewhere.

A **user-agent restriction** controls which players or apps can request the video, matching the User-Agent string against an allow or deny list. Because the User-Agent is set by the client and can be spoofed, treat it as an extra filter, and pair it with a private policy when access must be enforced.

For example, you can allow playback only from a desktop Chrome browser and block a specific Android device:

| Rule      | User-Agent                                                                                                                            |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| ✅ Allowed | `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Safari/537.36`               |
| ❌ Denied  | `Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/138.0.0.0 Mobile Safari/537.36` |

The same idea applies to domains: you keep an allowed list and a denied list, and set a default for anything not on either list.

Based on our analysis of real traffic, some non-browser user agents are never a genuine viewer. We recommend adding the following to your deny list to stop bot attacks and unauthorized downloading:

* **Download managers:** Internet Download Manager (`idm`), `1DM`, `1tap`, `XDM`, `FDM`, `JDownloader`, `aria2`
* **Command-line and HTTP clients:** `curl`, `wget`, `libcurl`, `python-requests`, `python-urllib`, `urllib`, `go-http-client`, `java`, `okhttp`, `axios`, `node-fetch`, `got`, `httpx`, `aiohttp`, `Scrapy`
* **Android download components:** `AndroidDownloadManager`, `Dalvik`
* **Media tools:** `ffmpeg`, `VLC`, `Lavf`, `libav`
* **Headless and automated browsers:** `HeadlessChrome`, `PhantomJS`, `Puppeteer`, `Playwright`

See [Restrict playback access](/docs/video-security/restrict-playback-access) to set them up.

\


## How JWT token playback works

A **JWT token** is a short, signed token your server creates for each viewer. FastPix checks it before serving any video.

```mermaid
flowchart TD
  B["<b>1. Your server signs a JWT token</b><br />using your private signing key"]
  C["<b>2. Your app opens the playback URL</b><br />with the token attached"]
  D{"<b>3. FastPix verifies the token</b><br />using the matching public key"}
  E["<b>Video plays</b>"]
  F["<b>Playback is refused</b>"]

  B --> C --> D
  D -->|"Token valid and not expired"| E
  D -->|"Token missing, expired, or tampered"| F

  classDef ok fill:#e6f4ea,stroke:#34a853,color:#0b6b2e;
  classDef no fill:#fce8e6,stroke:#ea4335,color:#a50e0e;
  class E ok;
  class F no;
```

To set it up:

1. **Create a signing key** with `POST /iam/signing-keys`. FastPix returns a key ID and an RSA private key, and keeps the matching public key. Store the private key on your server only.
2. **Sign a JWT token** for each viewer with three claims: `kid` (the key ID), `aud` set to `media:<playbackId>` (so the token works for one asset), and `exp` (a short expiry).
3. **Add the token to the URL** as a `token` query parameter: `https://stream.fastpix.com/<playbackId>.m3u8?token=<JWT>`.

> **Caution:** Sign tokens on your server, keep `exp` short, and never ship the private key or a long-lived token in client code.

For the full walkthrough, see [Generate JWTs for secure media](/docs/video-security/generate-jwts-for-secure-media) and [Secure media access with JWTs](/docs/video-security/secure-media-access-with-jwts).

\


## What is and is not protected

> **Note:** Nothing stops someone pointing a phone camera at the screen and filming it. Treat DRM the way streaming services do: strong protection for premium content such as films and paid courses, but, just like Netflix, not a 100% guarantee. How well it blocks screenshots and recording also depends on the viewer's device. DRM works for video on demand only and is off by default; contact FastPix support to turn it on.

Access control decides who can start playback. It does not control what an authorized viewer does with the video on their own screen. Only DRM protects the content itself, and even then within limits.

| Threat                   | Without DRM                                                                                                    | With DRM                                                                                                                   |
| ------------------------ | -------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| **Screenshots**          | Not prevented once the video is playing.                                                                       | Blocked, a screenshot of the video comes out black on most devices.                                                        |
| **Screen recording**     | Not prevented. Domain and user-agent rules do not stop an authorized viewer.                                   | Blocked, the recording comes out black on most devices.                                                                    |
| **Downloading the file** | Harder, not prevented. Tokens expire and stop hotlinking, but a determined viewer can still capture the video. | Strongly protected. The file is encrypted, so a downloaded copy is scrambled and will not play outside an approved player. |

\


## Watermarking

Add visible watermarks using FastPix's watermarking feature, which embeds them directly into the video and prevents misattribution. This doesn't support per-user or forensic watermarking, but you can add per-user watermarks by overlaying images on your player - just know these are easier to bypass since they're not baked into the video. Forensic watermarking isn't currently available, but if it would be valuable for your use case, let us know. We'd love to hear your feedback.

\


## Choose the right mechanism

* **Token-gate access (courses, paywalls, member-only):** private media with a JWT token. Your server signs a token only after the viewer logs in or pays, and it expires, so a shared link stops working on its own.
* **Limit embedding to your own sites:** domain restrictions, so the video plays only on domains you own. Pair with a private policy, since the domain check alone can be bypassed.
* **Limit playback to your own app:** user-agent restrictions, as an extra filter. The User-Agent can be faked, so back it with a private policy when access must be enforced.
* **Premium content that must resist copying:** DRM. It encrypts the video and, on supporting devices, blocks screenshots and recording. It is video on demand only and off by default, so contact FastPix support to enable it.
* **Show the video is yours even if it gets re-shared:** a visible [watermark](/docs/video-on-demand/add-a-watermark-to-a-video) baked into the video. It stays on every copy but does not stop copying, so combine it with the options above.

\


#### Frequently asked questions

A JWT token controls who is allowed to start playback and for how long. DRM encrypts the video itself so it only plays inside a protected player, and on supporting devices also blocks screenshots and recording. Tokens are access control; DRM is content protection. Many setups use both.

No. A JWT token controls who can begin playback; it does not stop an authorized viewer from recording or capturing the stream once it plays. To resist copying, use DRM.

Not completely. On enforcing devices (FairPlay on iOS, Widevine L1 on Android, PlayReady on Windows) it blocks them. Under software DRM in a desktop browser it often does not, and nothing prevents filming the screen with another camera.

Not directly. Create a new playback ID with the policy you want and delete the old one. Making an asset private does not revoke public URLs already issued, so regenerate the playback ID to cut them off.

\


## What's next

* [Generate JWTs for secure media](/docs/video-security/generate-jwts-for-secure-media)
* [Secure media access with JWTs](/docs/video-security/secure-media-access-with-jwts)
* [Restrict playback access](/docs/video-security/restrict-playback-access)
* [Set up DRM encryption](/docs/video-security/set-up-drm-encryption)