JSON Web Tokens are an open, industry standard method for representing claims securely between two parties. Mux APIs leverage JWTs to authenticate requests.
JWTs are made up of a header, a payload, and a signature. The header contains metadata useful for decrypting the rest of the token. The payload contains configuration options. And the signature is generated from a signing key-pair. More information can be found at jwt.io.
In order to sign the JWT you must create a signing key. Signing keys can be created from the Signing Keys section of the Mux Dashboard or via the Mux System APIAPI. This key-pair will be used by a cryptographic function to sign JWTs.
While developing an app, you may want an easy way to generate JWTs locally because you're not yet ready to set up a full blown production system that signs JWTs for client-side applications. There are a few different options for generating these JWTs.
Pasting credentials into a web browser is generally a bad practice. This web-based tool signs JWTs on the client which means your credentials never leave your machine. This is a tool designed by Mux, intended to be used with Mux credentials, and will always be hosted on a Mux domain. Never use a tool like this if it is hosted on a non-Mux domain.
Mux provides a web based JWT Signer at https://jwt.mux.dev. Simply input the Signing key-pair and configure the claims you wish to test your app with. Then, copy the JWT into your application code and run it.
Mux provides a Node.js based CLI for performing common tasks including signing JWTs for playback IDs.
After installing Node.js, the Mux CLI must be initialized with an Access Token. Follow this guide to create an Access Token. With your newly created Access Token, initialize the Mux CLI.
npx @mux/cli init
Now that the Mux CLI is initialized with your credentials, you can sign a JWT for Video Playback.
npx @mux/cli sign PLAYBACK-ID
For more details, refer to https://github.com/muxinc/cli.
You should only sign a JWT on the server, where you can keep your signing key secret. You should not put your signing key in the client itself.
Setup a REST endpoint behind your own authentication system that provides your client-side code with signed JWTs. That way, the sensitive secret from the signing key-pair stays on the server instead of being included in the client.
Once you're ready for customers to start using your app, you need a way to sign JWTs securely at-scale. Use the code examples below depending on which Mux product you would like to sign JWTs for.
package main
import (
"encoding/base64"
"fmt"
"log"
"time"
"github.com/golang-jwt/jwt/v4"
)
func main() {
myId := "" // Enter the id for which you would like to get counts here
myIdType := "" // Enter the type of ID provided in my_id; one of video_id | asset_id | playback_id | live_stream_id
keyId := "" // Enter your signing key id here
key := "" // Enter your base64 encoded private key here
decodedKey, err := base64.StdEncoding.DecodeString(key)
if err != nil {
log.Fatalf("Could not base64 decode private key: %v", err)
}
signKey, err := jwt.ParseRSAPrivateKeyFromPEM(decodedKey)
if err != nil {
log.Fatalf("Could not parse RSA private key: %v", err)
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"sub": myId,
"aud": myIdType,
"exp": time.Now().Add(time.Minute * 15).Unix(),
"kid": keyId,
})
tokenString, err := token.SignedString(signKey)
if err != nil {
log.Fatalf("Could not generate token: %v", err)
}
fmt.Println(tokenString)
}
package main
import (
"encoding/base64"
"fmt"
"log"
"time"
"github.com/golang-jwt/jwt/v4"
)
func main() {
playbackId := "" // Enter your signed playback id here
keyId := "" // Enter your signing key id here
key := "" // Enter your base64 encoded private key here
decodedKey, err := base64.StdEncoding.DecodeString(key)
if err != nil {
log.Fatalf("Could not base64 decode private key: %v", err)
}
signKey, err := jwt.ParseRSAPrivateKeyFromPEM(decodedKey)
if err != nil {
log.Fatalf("Could not parse RSA private key: %v", err)
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, jwt.MapClaims{
"sub": playbackId,
"aud": "v",
"exp": time.Now().Add(time.Minute * 15).Unix(),
"kid": keyId,
})
tokenString, err := token.SignedString(signKey)
if err != nil {
log.Fatalf("Could not generate token: %v", err)
}
fmt.Println(tokenString)
}