The first step is to generate a keypair and add that to our enterprise video CMS. If you haven’t already, please see how do I create a JWT?. Assuming you have, you should have a key ID. You will use that value as the JWT’s Key ID kid in a moment.

  1. In this example we have used NodeJS to make the JWT. But each language will have a way to make a JWT as it is a common method of authentication. Here we have used the popular npm package jsonwebtoken:
npm install jsonwebtoken
  1. In your app, include that:
const jwt = require('jsonwebtoken');
  1. You need to spcify these four values in the header:

The algorithm: that is always RS256.

The expiresIn: this is a string specifying how long the JWT is valid for.

The subject: this is either * to authenticate a request for any video in your account, or a specific video ID.

The keyid: this is that value mentioned above: the key ID we assigned when you provided your public key to us. So we know which of your JWT keys to check the signature against.

Now you can make a JWT, signed with your private key. For example:

let privateKey = fs.readFileSync('private.key');

let token = jwt.sign({}, privateKey, {
    algorithm: 'RS256',
    expiresIn: '1h',
    subject: '*',
    keyid: 'YOUR-KEY-ID'
});

The resulting variable will be a long string. You can append that token to requests for a private video for its:

  • landing page
  • embed code
  • direct HLS manifest

… as shown below for the respective URLs (replacing VIDEO-ID and JWT-HERE):

https://watch.vidbeo.com/VIDEO-ID?jwt=JWT-HERE
https://watch.vidbeo.com/VIDEO-ID/embed.html?jwt=JWT-HERE
https://watch.vidbeo.com/VIDEO-ID/hls.m3u8?jwt=JWT-HERE

When we receive a request for a private video, we check to see if the viewer is authenticated. We check for a valid cookie or a valid JWT in the request. So in this case, a JWT has been sent. It checks the key ID and if its digital signature matches then we know it was indeed signed by you. And so we should approve the request and return the relevant content. So, a landing page in the case of the URL above.

Note: Since we also allow authentication using a cookie, make sure you are signed out of our video CMS when testing a JWT-protected URL. Else you may get unexpected results

Restrict to a single video

You can limit the JWT’s access so that it can only be used to access a single private video. Simply pass the video’s ID as the subject. For example:

let token = jwt.sign({}, privateKey, {
    algorithm: 'RS256',
    expiresIn: '1h',
    subject: 'VIDEO-ID',
    keyid: 'YOUR-KEY-ID'
});

Restrict using custom claims

You can pass custom claims in the JWT’s payload. We support a limited number:

  • countries
  • domains (experimental)

You set these within an allow object. Pass its lowercase two-character country code, in an array, in the JWT’s payload. For example:

let token = jwt.sign({
    allow: {
        countries: ['gb']
    }
}, privateKey, {
    algorithm: 'RS256',
    expiresIn: '24h',
    subject: 'VIDEO-ID',
    keyid: 'YOUR-KEY-ID'
});

We also support only letting a JWT be used from certain domains. The complication here is that some sites have a Content Security Policy (CSP) that blocks the referer domain from being sent to us to tell us the domain. And so we have no way of knowing if the JWT is being used for a domain you actually do want to allow. And so to be safe, have to block the request. Which could result in your videos being blocked for your viewers, despite presenting a valid JWT.

The other problem with restricting by domain is it can be faked. Someone can fake a referer URL and so pretend to be using another domain. And so bypassing this protection.

This is how it works if you do want to try it out:

let token = jwt.sign({
    allow: {
        domains: ['example.com']
    }
}, privateKey, {
    algorithm: 'RS256',
    expiresIn: '24h',
    subject: 'VIDEO-ID',
    keyid: 'YOUR-KEY-ID'
});

If you have any questions, please email us to ask.