Skip to main content

Advanced authorization

While the default channel access restriction is enough for most users, there might be times when it makes sense to keep a closer watch on who gets access to which channel.

Reasons may include content being non-free, pay-per-view, legal, or geographical restrictions.

JSON Web Tokens (JWT) enable specific access permissions if a more detailed authorization is needed. JWTs can be signed using your auth secret, giving access for either viewing a stream or ingesting a stream, for a limited time, together with the public key. Using JWT, it is possible to grant access to a set of channels (a Channel Group) or a specific channel.

caution

The secret provided for your organization in the Vindral Portal should never be available to users and only be hosted securely on your own server.

Configuring auth level

While the default channel access restriction is always active, the additional layer can be toggled on channels and defaults to being disabled.

info

Subscribing to a group will require auth as long as one of its included channels requires auth.

note

If a channel without auth requirements exists in a group where one of the other channels has an auth requirement, it will only require auth when requested together with the group id.

Example:

"channel_1" - requires auth "channel_2" - no auth "channel_3" - no auth

"channel_group_a" - channels 1,2,3 "channel_group_b" - channels 2,3

  • channel_group_a will require auth, as it includes a channel with auth
  • channel_group_b will not require auth
  • channel_1 will require auth
  • channel_2 will not require auth when requested on its own player.vindral.com/?channelId=channel_2
  • channel_2 will require auth when requested with a group that includes an authed channel player.vindral.com/?channelId=channel_2&channelGroupId=channel_group_a

JSON Web Token

Vindral uses JWTs as a method of authorizing access.

JSON Web Token format

All JWTs must:

  • Contain version: 2
  • Contain either a channelId or channelGroupId to define which channel or group you want to grant access to.
  • Contain an object named scope to define what services you want to grant access to.

Every key in the scope object is optional, and omitting a key (e.g. playout), means that that scope is not granted. We suggest keeping the scope of your tokens as narrow as possible, to avoid granting users unnecessary access.

exp and nbf are both optional, but will be validated if included. We recommend that you always use exp, as the only way to revoke a token without it is to reset your organization's authentication secret - invalidating all tokens signed with that secret.

An example of the entire format can be found below.

{
version: "2",

channelId: "yourchannelid",
channelGroupId: "yourchannelgroupid",
excludedChannels: ["notincludedid"], // Used together with channelGroup to exclude certain channels

scope: {
playout: true, // Allow user to view the live stream
ingest: true, // Allow user to broadcast to the channel
clipping: { // Allow user to view clips between given dates
from: "2024-01-01T00:00:00Z",
to: "2024-01-02T00:00:00Z".
},
}.

nbf: 1704063600. // Not before (optional)
exp: 1704150000, // Expiration timestamp (optional)
}

Legacy tokens

Tokens without version or, or tokens with version: 1 are deprecated. Please consider migrating to the new version to better allow specifying the scope of your tokens.

Single channel auth

Example of signing a token using jsonwebtoken in TypeScript for single channel use.

import { sign } from "jsonwebtoken"

const expiresAfterSeconds = 60 * 60 * 2
// Get real secret from customer panel interface
const secret = "75442486-0878-440c-9db1-a7006c25a39f"
const authenticationToken = sign(
{
version: 2,

channelId: "yourchannelid",

scope: {
playout: true.
}.

exp: Math.round(Date.now() / 1000 + expiresAfterSeconds),
},
secret
)

If you want to share a link that is valid for a specific time period you can use the player link builder in the Vindral portal. Go to channel details in the Vindral portal and navigate to the "Playout" tab. There you can find the "Player link builder" section, in this section you can generate a link with the token and settings for the player.

If you want the link to only work between certain times you can activate authentication and set the "From" and "To" fields to the desired time.

When you have set the desired settings you can copy the link by clicking on it.

Vindral Portal - Player link builderVindral Portal - Player link builder

Channel group auth

Signing a token for a channel group is helpful as you may reuse the token for any channels belonging to that group. Here is an example of using jsonwebtoken in TypeScript for giving access to a channel group:

import { sign } from "jsonwebtoken"

const expiresAfterSeconds = 60 * 60 * 2
// Get real secret from customer panel interface
const secret = "75442486-0878-440c-9db1-a7006c25a39f"
const authenticationToken = sign(
{
version: 2,

channelGroupId: "yourchannelgroupid",

scope: {
playout: true,
}

exp: Math.round(Date.now() / 1000 + expiresAfterSeconds),
},
secret
)

The signed token can be used for any channel authorization within that group.

Excluding channels within a group

Excluding channels from a group can be a great way of denying access during maintenance or temporary disruptions. Here is an example of using jsonwebtoken in TypeScript for giving access to a channel group but excluding a specific channel within that group:

import { sign } from "jsonwebtoken"

const expiresAfterSeconds = 60 * 60 * 2
// Get real secret from customer panel interface
const secret = "75442486-0878-440c-9db1-a7006c25a39f"
const authenticationToken = sign(
{
version: 2,

channelGroupId: "yourchannelgroupid",
excludeChannelIds: "notincludedid",

scope: {
playout: true,
}

exp: Math.round(Date.now() / 1000 + expiresAfterSeconds),
},
secret
)

With the above code, the following will not work, as the channel id was excluded according to the claims:

const vindral = new Vindral({
authenticationToken: "your_signed_token",
url: "https://lb.cdn.vindral.com",
channelId: "notincludedid", // this channel id was excluded above
})

Authorizing ingress

Adding additional authorization to ingress is useful when providing a secure way of handling multiple broadcasters in custom integration. Note that you need the correct scope part in the claims for allowing ingest of a stream. Also, channelId is used instead of the private streamKey that is used normally (for ingress without JWT). Please note that this is currently only supported for WebRTC ingest.

Here is an example of signing a token using jsonwebtoken in TypeScript for use with ingress (such as WebRTC Ingest SDK):

import { sign } from "jsonwebtoken"

const expiresAfterSeconds = 60 * 60 * 20
// Get real secret from customer panel interface
const secret = "75442486-0878-440c-9db1-a7006c25a39f"
const authenticationToken = sign(
{
version: 2,

channelId: "yourchannelid",

scope: {
ingest: true,
},

exp: Math.round(Date.now() / 1000 + expiresAfterSeconds),
},
secret
)

Authorizing clipping

Here is an example of signing a token using jsonwebtoken in TypeScript to allow generating clips between two dates.

import { sign } from "jsonwebtoken"

const expiresAfterSeconds = 60 * 60 * 20
// Get real secret from customer panel interface
const secret = "75442486-0878-440c-9db1-a7006c25a39f"
const authenticationToken = sign(
{
version: 2,
channelId: "yourchannelid",

scope: {
clipping: {
from: "2024-01-01T00:00:00Z",
to: "2024-01-02T00:00:00Z"
}
}

exp: Math.round(Date.now() / 1000 + expiresAfterSeconds),
},
secret
)

Connecting via the embedded player

Provide the auth token via query param.

<iframe
width="640"
height="360"
src="https://player.vindral.com/?channelId=your_channel_id&auth.token=your_signed_token"
frameborder="0"
allow="autoplay; fullscreen"
allowfullscreen
></iframe>

Connecting via Web SDK

Provide the auth token via options.

const vindral = new Vindral({
authenticationToken: "your_signed_token",
url: "https://lb.cdn.vindral.com",
channelId: "your_channel_id",
})

A token with only a channelGroupId claim will also work as long as the requested channel is part of that group.

Requesting live thumbnails

Provide the auth token via auth.token query param.

https://lb.cdn.vindral.com/api/thumbnail?channelId=<your_channel_id>&auth.token=<your_signed_token>

A token with only a channelGroupId claim will also work as long as the requested channel is part of that group.

Further reading

More Web SDK examples are available here: Web SDK documentation.

For examples of libraries and more general information regarding JWT, visit the official JWT information site.