Important changes to Tiny Cloud pricing > Find out more

RTC JWT Authentication

Guide on how to setup JWT Authentication for RTC

Contribute to this page

Important: The RTC plugin is currently in Open Beta. To learn about our pre-release commitment, please read our software licence agreement.

Introduction

RTC requires setting up JSON Web Token (JWT) authentication. This is to ensure that only authenticated users will be able to access and collaborate on documents.

JWT is a standard authorization solution for web services and is documented in more detail at the https://jwt.io/ website. This guide aims to show how to setup JWT authentication for RTC.

Private/public key pairs for Tiny Cloud services

Tiny Cloud services tokens use public/private RSA key pairs. The Tiny Cloud services only store the public key, allowing developers to have full control over the authentication.

The private/public key pair can be created on your Tiny - Tiny Account page, however the public key is only stored on the Tiny Account. The private key should be downloaded and stored in your backend.

Important: Keep the private key secure. Do not commit files containing the key to public repositories or websites.

For information on generating a RSA key pair locally, see: Creating a private/public key pair for RTC.

JWT provider endpoint URL

The easiest way to setup JWT authentication for Tiny Cloud services is to create a JWT provider endpoint. This endpoint takes a JSON HTTP POST request and produces a JSON response with the token that the service can then use for all HTTP requests.

The following diagram explains the JWT call flow:

JSON Web Token Call Flow

JWT requirements

Supported algorithms

Tiny recommends using the RS256 algorithm. The following algorithms are supported:

  • RS256
  • RS384
  • RS512
  • PS256
  • PS384
  • PS512

For details on each of these algorithms, visit: RFC 7518, JSON Web Algorithms (JWA) Section 3 - Cryptographic Algorithms for Digital Signatures and MACs.

Claims

Claims are additional data that can be sent as part of the JWT token. The RTC JWT requires the following claims:

Data Optional or required Description
sub required The unique user ID (for example, if sub is the same for two clients, you should trust them as if they’re the same user).
exp required The timestamp when the token expires.

The sub field is used to identify users to avoid sending sensitive or identity information to Tiny in plain text. By minimizing the information in JWT claims and relying on the client-side resolution of user IDs, no private data will be transmitted through the RTC server without encryption.

JWT endpoint setup procedure

Follow these steps to set up a JWT endpoint.

  1. Setup a JWT endpoint on your server. Examples have been provided below.
  2. Configure the rtc_token_provider to point to that endpoint.
  3. Copy the private key into the example code.

The JWT Endpoint should examine your systems sessions to verify your user has access to your system.

Generating a secure encryption key

Caution: These suggestions may not guarantee a secure connection. If data secrecy is important to you please consult a security professional.

Encryption security is a trade off between the complexity of generating a key and the risk of compromise should the key be disclosed to an unknown third party. Here are some suggested ways to generate keys, in descending order of safety:

  • Store a global list of keys for your application, and use the document ID along with random data to salt the current key on your server to produce a key unique to the document session. Do not return the salt data to keyHint; return an identifier that can be used to look up the unique key on the server.
  • Use a fixed random key for each document, and generate random salt data to provide a unique key for each session. Pass the salt data to keyHint.
  • Generate and store a fixed random key for each document in your database. Ignore the keyHint input field and return a fixed arbitrary keyHint value.

Encryption key rotation and key hints

The RTC configuration API is designed to support key rotation. Keys cannot be rotated on demand; if this is important to you, please contact Tiny to discuss how we can best provide that functionality.

Document collaboration may be performed in multiple sessions. For example, when a new version of TinyMCE is deployed it may be incompatible with existing sessions. Only one session will be active at a time but older sessions may still be used to bootstrap new sessions. As such, old keys cannot be immediately discarded when a new key is requested.

In order to allow for key rotation, a key hint is supplied so the provider may tell the difference between these two cases and act accordingly. If the key hint is null, then the client wants the “current” key and can be issued a key different from any previously used key. If the key hint is set, then the client is requesting a previously-issued key so that it can read the session history.

A specific key hint may be specified in the key response. If it is not specified, then an empty string will be sent when the client requests that key in future.

Warning: The key hint is transmitted in plain text. Do not store secret or sensitive information in the key hint.

The key hint can be a key thumbprint, ID, or other non-sensitive identifier that will help select the key, such as a timestamp. It is only recorded when keyHint is null in the request.

Need help?

Tiny recommends looking into how JWT works; some knowledge about JWT is necessary to implement RTC. This can be tricky, so if you need some help contact our support team.

PHP token provider endpoint example

This example uses the Firebase JWT library provided through the Composer dependency manager.

$privateKey should be a private key generated at Tiny Account.

jwt.php

<?php
require 'vendor/autoload.php';
use \Firebase\JWT\JWT;

header("Access-Control-Allow-Origin: *");
header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");

$privateKey = <<<EOD
-----BEGIN PRIVATE KEY-----
....
-----END PRIVATE KEY-----
EOD;

// NOTE: Before you proceed with the TOKEN, verify your users session or access.

$payload = array(
  "sub" => "123", // unique user ID string
  "exp" => time() + 60 * 10 // 10 minute expiration
);

try {
  $token = JWT::encode($payload, $privateKey, 'RS256');
  http_response_code(200);
  header('Content-Type: application/json');
  echo json_encode(array("token" => $token));
} catch (Exception $e) {
  http_response_code(500);
  header('Content-Type: application/json');
  echo $e->getMessage();
}
?>

TinyMCE example with jwt.php Endpoint

tinymce.init({
  selector: 'textarea', // change this value according to your HTML
  plugins: 'rtc',
  rtc_token_provider: () => {
    return fetch('jwt.php', {
      method: 'POST'
    });
  }
});

Node token provider endpoint example

This example shows how to set up a Node.js express handler that produces the tokens. It requires you to install the Express web framework and the jsonwebtoken Node module. For instructions on setting up a basic NodeJS Express server and adding TinyMCE, see: Integrating TinyMCE into an Express JS App.

privateKey should be a private key generated at Tiny Account.

/jwt

const express = require('express');
const jwt = require('jsonwebtoken');
const cors = require('cors');

const app = express();
app.use(cors());

const privateKey = `
-----BEGIN PRIVATE KEY-----
....
-----END PRIVATE KEY-----
`;

app.post('/jwt', function (req, res) {
  // NOTE: Before you proceed with the TOKEN, verify your users' session or access.
  const payload = {
    sub: '123', // Unique user ID string
    exp: Math.floor(Date.now() / 1000) + (60 * 10) // 10 minutes expiration
  };

  try {
    const token = jwt.sign(payload, privateKey, { algorithm: 'RS256'});
    res.set('content-type', 'application/json');
    res.status(200);
    res.send(JSON.stringify({
      token: token
    }));
  } catch (e) {
    res.status(500);
    res.send(e.message);
  }
});

app.listen(3000);

TinyMCE example with /jwt endpoint

tinymce.init({
  selector: 'textarea', // change this value according to your HTML
  plugins: 'rtc',
  rtc_token_provider: () => {
    return fetch('/jwt', {
      method: 'POST'
    });
  }
});

More configuration

Once JWT authentication has been set up, the RTC plugin can be configured further using the options shown on the RTC configuration options page. Don’t forget to change the example JWT claims (user id, user name) to get those from your system.

If you want help submit a support request.

Creating a private/public key pair for RTC

The procedure for creating a key pair depends on the operating system of the host machine.

Linux

To create a private/public key pair on a Linux operating system:

  1. Install OpenSSL.
  2. Create a private/public key pair.
  3. Retrieve the public key.

Installing OpenSSL on Linux

The procedure for installing OpenSSL on Linux distributions varies. The installation commands for common Linux distributions have been provided here.

Red Hat Enterprise Linux 7 or CentOS 7

On a command line, run the following commands to install OpenSSL on:

  • Red Hat Enterprise Linux 6 or 7.
  • CentOS 6 or 7.
sudo yum check-update
sudo yum install openssl
Red Hat Enterprise Linux 8+, Fedora, or CentOS 8+

On a command line, run the following commands to install OpenSSL on:

  • Red Hat Enterprise Linux 8 or later.
  • CentOS 8 or later.
  • Fedora 18 or later.
sudo dnf check-update
sudo dnf install openssl
Debian, Ubuntu, Linux Mint, or other Debian-based distributions

On a command line, run the following commands to install OpenSSL on Debian-based operating systems (such as: Debian, Ubuntu, and Linux Mint).

sudo apt update
sudo apt install openssl
SUSE Linux Enterprise Server or openSUSE

On a command line, run the following commands to install OpenSSL on openSUSE-based operating systems (such as: openSUSE and SUSE Linux Enterprise Server).

sudo zypper refresh
sudo zypper install openssl

Create a private/public key pair on Linux

To create a private/public key pair:

  1. On a command line, run:

     ssh-keygen -m PEM -t rsa -b 2048 -f <MY_KEY_PAIR_NAME>
    

    Where <MY_KEY_PAIR_NAME> should be replaced with a name for the key pair.

  2. Enter a passphrase for accessing the key.

Two files will be created in the current directory:

  • <MY_KEY_PAIR_NAME> - The private key.
  • <MY_KEY_PAIR_NAME>.pub - The public key.

Retrieve the public key on Linux

To retrieve the public key, on a command line, run:

openssl rsa -in <MY_KEY_PAIR_NAME> -outform DER -pubout | base64 -w0

The public key for the <MY_KEY_PAIR_NAME> key pair will be printed on the command line with base64 encoding.

Apple macOS

To create a private/public key pair on a macOS operating system:

  1. Create a private/public key pair.
  2. Retrieve the public key.

Create a private/public key pair on macOS

To create a private/public key pair:

  1. Using Finder, open a Terminal.
  2. On a terminal, run:

     ssh-keygen -m PEM -t rsa -b 2048 -f <MY_KEY_PAIR_NAME>
    

    Where <MY_KEY_PAIR_NAME> should be replaced with a name for the key pair.

  3. Enter a passphrase for accessing the key.

Two files will be created in the current directory:

  • <MY_KEY_PAIR_NAME> - The private key.
  • <MY_KEY_PAIR_NAME>.pub - The public key.

Retrieve the public key on macOS

To retrieve the public key, on a terminal, run:

openssl rsa -in <MY_KEY_PAIR_NAME> -outform DER -pubout | base64 -

The public key for the <MY_KEY_PAIR_NAME> key pair will be printed on the terminal with base64 encoding.

Microsoft Windows

To create a private/public key pair on a Microsoft Windows operating system:

  1. Install OpenSSL.
  2. Create a private/public key pair.
  3. Retrieve the public key.

Installing OpenSSL on Microsoft Windows

To install OpenSSL with Git for Windows:

  1. Download the Windows package from the Git Downloads page.
  2. Open the downloaded file Git-<VERSION>-<ARCH>-bit.exe, where <VERSION> is the latest version of Git for Windows and <ARCH> is the architecture, such as 32-bit or 64-bit.
  3. Click Next on the Information and Select Destination Location screens.
  4. Select Check daily for Git for Windows updates on the Select Components screen, then click Next.
  5. Click Next on the remaining screens to accept the default settings.
  6. Once the installation is complete, click Finish.

Create a private/public key pair on Windows

To create a private/public key pair:

  1. Open the Start menu (or Windows menu) and open Git Bash.
  2. On the Git bash command line, run:

     ssh-keygen -m PEM -t rsa -b 2048 -f <MY_KEY_PAIR_NAME>
    

    Where <MY_KEY_PAIR_NAME> should be replaced with a name for the key pair.

  3. Enter a passphrase for accessing the key.

Two files will be created in the current directory:

  • <MY_KEY_PAIR_NAME> - The private key.
  • <MY_KEY_PAIR_NAME>.pub - The public key.

Retrieve the public key on Windows

To retrieve the public key, on a Git bash command line, run:

openssl rsa -in <MY_KEY_PAIR_NAME> -outform DER -pubout | base64 -w0

The public key for the <MY_KEY_PAIR_NAME> key pair will be printed on the command line with base64 encoding.

Can't find what you're looking for? Let us know.

Except as otherwise noted, the content of this page is licensed under the Creative Commons BY-NC-SA 3.0 License, and code samples are licensed under the Apache 2.0 License.