> 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.

# Secure live streaming

Secure a FastPix live stream so only the viewers you authorize can watch. FastPix live streams are public by default, so a ticketed event, a paid course or webinar, an internal town hall, or member-only OTT content needs the stream locked down: make it private, sign a token for each viewer, restrict where it plays, and protect the broadcast side.

This guide walks through every layer, from the encoder to the viewer.

\


## How FastPix secures a live stream

Security applies at four points between your encoder and your viewers. The playback URL is where FastPix decides whether a viewer may watch, and the per-segment checks make sure that decision cannot be bypassed by copying links.

| Where              | What is protected                           | How                                                                                 |
| ------------------ | ------------------------------------------- | ----------------------------------------------------------------------------------- |
| Encoder to FastPix | The broadcast and the stream key in transit | RTMPS or SRT, stream key required (section 5)                                       |
| FastPix delivery   | The storage and origin behind the stream    | Encrypted, tokenized delivery, origin never exposed (section 4)                     |
| Playback URL       | Who may start watching                      | Signed token for private streams, domain and user-agent checks (sections 2 and 3)   |
| Every segment      | Who may keep watching                       | Signed URLs that expire, restrictions re-checked on each request (sections 3 and 4) |

\


## Make a live stream private

A private stream plays only when the playback URL carries a valid token that your backend signs. Without a token, or with an expired or tampered one, playback is refused with `401 Unauthorized`.

**1. Create the stream with a private access policy.**

```bash
curl -X POST "https://api.fastpix.com/v1/live/streams" \
  -u "{Access_Token_ID}:{Secret_Key}" \
  -H "Content-Type: application/json" \
  -d '{
    "playbackSettings": { "accessPolicy": "private" },
    "inputMediaSettings": { "maxResolution": "1080p" }
  }'
```

The response contains the stream's `playbackIds`. To protect an existing stream, add a private playback ID with `POST /v1/live/streams/{streamId}/playback-ids` and stop sharing the public one.

**2. Create a signing key** in your FastPix workspace with `POST /v1/iam/signing-keys`. You get a key ID and an RSA private key. Keep the private key on your server only; FastPix stores just the public half to verify tokens.

**3. Sign a token on your server** for each viewer who is allowed to watch. It is a JWT signed with the private key using **RS256**, with these claims:

| Claim | Value                      | Purpose                                  |
| ----- | -------------------------- | ---------------------------------------- |
| `kid` | Your signing key ID        | Tells FastPix which key to verify with   |
| `aud` | `media:{playbackId}`       | The token works for this one stream only |
| `exp` | Expiry time (Unix seconds) | The token stops working after this       |

**4. Give the viewer the playback URL with the token:**

```
https://stream.fastpix.com/{playbackId}.m3u8?token={jwt}
```

FastPix checks the signature, that the key belongs to the stream's workspace, the audience, and the expiry before any video is served. Issue tokens only after your own login or paywall check, and keep `exp` short (for example the length of the event plus a margin), so a shared link soon stops working.

For the full signing-key and JWT details shared with on-demand playback, see [Generate JWTs for secure media](/docs/video-security/generate-jwts-for-secure-media).

\


## Restrict where a stream can play

Restrictions limit where a stream plays: on which websites, and in which apps or players. They work with public and private streams alike, and are checked on the playback URL and again on every playlist and segment request, so a blocked site cannot keep playing.

| Restriction  | Checks                                                                        | Entries                                                                                                    |
| ------------ | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `domains`    | The site the player is embedded on (from the browser's `Referer` or `Origin`) | Exact domains (`example.com` also covers its subdomains) or wildcards (`*.example.com`), up to 25 per list |
| `userAgents` | The player or app making the request                                          | Text the User-Agent must contain (for example `MyAppPlayer`), up to 25 per list                            |

Each restriction has a `defaultPolicy`:

* **`deny` plus an `allow` list (recommended):** only the listed sites or apps can play; everything else gets `403 Forbidden`.
* **`allow` plus a `deny` list:** everything can play except the listed sites or apps.

Set them when you create the stream:

```bash
curl -X POST "https://api.fastpix.com/v1/live/streams" \
  -u "{Access_Token_ID}:{Secret_Key}" \
  -H "Content-Type: application/json" \
  -d '{
    "playbackSettings": {
      "accessPolicy": "private",
      "accessRestrictions": {
        "domains":    { "defaultPolicy": "deny",  "allow": ["example.com", "*.example.com"] },
        "userAgents": { "defaultPolicy": "allow", "deny":  ["curl", "Wget"] }
      }
    }
  }'
```

Change them on a running stream with `PATCH /v1/live/streams/{streamId}/playback-ids/{playbackId}/domains` or `.../user-agents`. A change reaches viewers who are already watching within about 15 seconds, without them reloading.

> **Note:** User-agent text can be spoofed by a determined client, so treat it as an extra filter. For real access control, combine domain restrictions with a private access policy.

\


## Encrypted, tokenized delivery is built in

A FastPix live stream is public by default: anyone with its playback URL can watch. Even then, the delivery itself is protected, with nothing to turn on:

* **One public entry point.** Viewers only ever receive a FastPix playback URL (`https://stream.fastpix.com/{playbackId}.m3u8`). The storage and origin behind it are never exposed.
* **Tokenized playlists and segments.** Each quality level and each video segment is fetched with a signed token that FastPix issues and that expires. A copied segment or playlist link stops working once its token expires, so the stream cannot be lifted into another player for long.
* **A unique session per viewer.** Every playback gets its own encrypted session identifier, which FastPix uses to apply your restrictions and count concurrent viewers.
* **Encrypted transport.** All playback is served over HTTPS only.

This stops hot-linking and stale-link reuse, but it does not decide who may watch. For that, create the stream as private and add restrictions.

\


## Secure the broadcast side

Whoever holds a stream's key can broadcast on it, so the ingest side needs the same care as playback.

* **Use RTMPS, not RTMP.** RTMPS sends the video and the stream key over TLS, so neither can be read on the network. Use the RTMPS ingest URL from your stream's details in your encoder (OBS, vMix, Wirecast, and others support it). See [Live stream with RTMPS](/docs/live-streaming/live-stream-with-rtmps).
* **Or use SRT with its passphrase.** Each stream has its own `srtSecret`. SRT encrypts the whole broadcast with it, and connections without the right passphrase are refused during the handshake. See [Live stream with SRT](/docs/live-streaming/live-stream-with-srt).
* **Keep the stream key and SRT secret server-side.** Never put them in a web page, a mobile app, or a shared document. Give them only to the people or machines that broadcast.
* **If a key leaks, disable the stream right away** with `PUT /v1/live/streams/{streamId}/live-disable`: no one can broadcast or watch until you enable it again. Then create a new stream for the next broadcast.

\


## Secure live event checklist

Before you go live, confirm each of these:

* Stream created with `accessPolicy: private`.
* Signing key created; private key stored only on your server.
* Tokens signed per viewer after your login or paywall check, with a short `exp`.
* Domain restriction set to `deny` with your sites in `allow`.
* User-agent restriction added if only your own app or player should play.
* Encoder set to RTMPS (or SRT with the stream's passphrase).
* Stream key and SRT secret shared only with the broadcast team.
* Tested before going live: playback without a token and from an unlisted site should both be refused.

\


#### Frequently asked questions

Create the stream with a private access policy, then sign a short-lived RS256 JWT for each authorized viewer and append it to the playback URL (`https://stream.fastpix.com/{playbackId}.m3u8?token={jwt}`). Add domain and user-agent restrictions to limit where it plays, and broadcast over RTMPS or SRT so the ingest side is encrypted too.

Set `"accessPolicy": "private"` in the stream's `playbackSettings` when you create it with `POST /v1/live/streams`, or add a private playback ID to an existing stream and stop sharing the public one. A private stream then plays only with a valid signed token; requests without one are refused with `401 Unauthorized`.

RTMPS is RTMP over TLS. It encrypts the video and the stream key in transit, so neither can be read on the network, while plain RTMP sends them unencrypted. For a secure broadcast, use the RTMPS ingest URL in your encoder, or use SRT with its passphrase.

Add a `domains` restriction to the playback settings with `"defaultPolicy": "deny"` and your sites in the `allow` list, so every other site gets `403 Forbidden`. You can set it when you create the stream or change it on a running stream with `PATCH /v1/live/streams/{streamId}/playback-ids/{playbackId}/domains`; the change reaches current viewers within about 15 seconds.

Keep token `exp` short so a shared link soon stops working, and issue tokens only after your own login or paywall check. There is no per-viewer revocation, but you can disable the whole stream with `PUT /v1/live/streams/{streamId}/live-disable` if a key leaks, which stops all broadcast and playback until you enable it again.

Both. Even on public streams, each playlist and segment is fetched with a signed token that FastPix issues and that expires, and domain and user-agent restrictions are re-checked on every request. A copied segment or playlist link stops working once its token expires, so the stream cannot be lifted into another player for long.

\


## What's next

* [Create and manage live streams](/docs/live-streaming/create-and-manage-live-streams) to set up the stream this guide secures.
* [Generate JWTs for secure media](/docs/video-security/generate-jwts-for-secure-media) for the signing-key and token details.
* [Live stream with RTMPS](/docs/live-streaming/live-stream-with-rtmps) and [Live stream with SRT](/docs/live-streaming/live-stream-with-srt) for encrypted ingest.