TinyMCE AI JWT Authentication

TinyMCE AI requires JWT (JSON Web Token) authentication when using the Tiny Cloud service. JWT authentication provides secure, user-specific access to TinyMCE AI features. Each JWT token contains claims that identify the user and specify which AI features they can access.

TinyMCE recommends using the libraries listed on jwt.io/libraries to create JWT tokens. These libraries support the algorithms required by TinyMCE AI. For details on supported algorithms, see Supported Algorithms.

Trial: demo identity service

During a Tiny Cloud trial, a demo identity service is available for the TinyMCE AI plugin. This allows trying the plugin without setting up a custom token endpoint, for the duration of the trial. The demo service assigns a random session and user ID to the end user, then generates a JWT for that user. This prevents users from viewing each other’s conversation history.

Quick start

The following is the simplest way to use the demo identity service. Replace {apiKey} with the trial API key from the Customer Portal.

In production, the user session should be scoped to the page, not a specific TinyMCE instance. This example places it in the tinymceai_token_provider option for ease of use. If there are multiple TinyMCE instances on the page, this may cause unexpected behavior regarding users. In that case, run the session fetch only once per page.

const apiKey = 'no-api-key'; // Replace with the trial API key from the Customer Portal

tinymce.init({
  selector: 'textarea',
  plugins: 'tinymceai',
  toolbar: 'tinymceai-chat tinymceai-quickactions tinymceai-review',
  tinymceai_token_provider: async () => {
    // Step 1: Set up a random session
    await fetch(`https://demo.api.tiny.cloud/1/${apiKey}/auth/random`, { method: "POST", credentials: "include" }).then((resp) => resp.json());

    // Step 2: Get a JWT
    const jwtRes = await fetch(`https://demo.api.tiny.cloud/1/${apiKey}/jwt/tinymceai`, { credentials: "include" });
    const token = await jwtRes.text();
    return { token };
  }
});

Realistic usage

In production, user and session management typically happens at the page level. This example gives a more realistic pattern for using the demo identity service’s two endpoints:

// Step 1: Set up session - this should be part of the application's user management process. We simulate that here by creating a session for a random user.
const apiKey = 'no-api-key'; // Replace with the trial API key from the Customer Portal
const isLoggedIn = fetch(`https://demo.api.tiny.cloud/1/${apiKey}/auth/random`, { method: "POST", credentials: "include" });

tinymce.init({
  selector: 'textarea',
  plugins: 'tinymceai',
  toolbar: 'tinymceai-chat tinymceai-quickactions tinymceai-review',
  tinymceai_token_provider: async () => {
    // Step 2: Ensure session exists, then fetch the JWT
    return isLoggedIn.then(() =>
      fetch(`https://demo.api.tiny.cloud/1/${apiKey}/jwt/tinymceai`, { credentials: "include" })
        .then(resp => resp.text())
        .then(token => ({ token }))
    );
  }
});

Moving to production

To move from the demo identity service to a production system:

  1. Replace the session call with your own user management. If there is no concept of users, generate a randomized identifier per session or page so end users do not share conversation history.

  2. Set up a JWT endpoint that creates JWTs as described in this guide. Replace the JWT fetch with a call to your endpoint. See Node.js or PHP for implementation guides.

Token Endpoint Overview

To connect TinyMCE with TinyMCE AI, a token endpoint must be created in the application backend. This guide outlines the principles required to create that endpoint.

How TinyMCE AI Uses Tokens

To authenticate users, TinyMCE AI uses tokens. The purpose of tokens is to inform the AI service that the user has access to AI features and which API key the user should connect to. The authenticity of tokens is provided by a digital signature.

The token endpoint is where TinyMCE makes a request to get the token. It is required to return the token only if the user proves their identity. It should be placed inside the system, not exposed as a public endpoint without proper authentication.

The following diagram shows how TinyMCE AI uses tokens:

JSON Web Token Call Flow
Figure 1. JSON Web Token Call Flow

The JSON Web Tokens Specification

TinyMCE AI tokens are represented as JSON Web Tokens (JWT). JWT is an open standard (RFC 7519) for transmitting digitally signed information. Using it ensures that the data comes from a trusted source and has not been tampered with.

A JWT consists of three parts separated by dots .

  • Header: Contains metadata about the token, including the signing algorithm

  • Payload: Contains the claims (user information, permissions, and similar)

  • Signature: Used to verify the token’s authenticity

{header}.{payload}.{signature}
Example:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLTQ4NzI5IiwibmFtZSI6Ikplc3NpY2EgV2lsbGlhbXMiLCJpYXQiOjE3Mjg0NzM2NDJ9.kX9mP2qL8vN4rT7wY3zA5bC6dE1fG2hI3jK4lM5nO6pQ7rS8tU9vW0xY1zA2b

Header

The JWT header identifies the token type and specifies the cryptographic algorithm used to sign the token. For TinyMCE AI, the header must be a JSON object containing:

  • alg: The signing algorithm used to create the token signature. See Supported Algorithms for the list of supported algorithms. Tiny recommends using RS256.

  • typ: The token type identifier, which must always be JWT

The header is Base64URL-encoded to form the first part of the JWT token.

Example header
{
  "alg": "RS256",
  "typ": "JWT"
}

Payload

The JWT payload is a JSON object containing claims that identify the user, specify their AI permissions, and control token validity. The payload is Base64URL-encoded to form the second part of the JWT token.

Payload Properties

The following properties must be included in the payload:

  • aud: The API key that has entitlements to use TinyMCE AI.

  • sub: The user ID. This should be a unique identifier for the user making the request. This identifier is used to lock down conversation history, AI-generated content, and other user-specific data to individual users, ensuring privacy and data isolation.

  • iat: "Issued at". Ensure iat is present and contains a correct time stated in seconds. Some JWT implementations do not include it by default. Sometimes the system time may also be invalid, causing issues.

  • exp: Token expiration time. Identifies the expiration time after which the JWT will not be accepted. TinyMCE AI only accepts tokens no older than 24 hours. This field can be used to shorten the token validity time.

  • auth: The auth.ai.permissions array inside is required. This defines which AI features the user can access. See Permissions below for details.

The properties that are optional:

  • user: User information. Providing name and email is recommended for better user experience and debugging.

Example Token Payload

The example below presents a complete token payload with access to all AI features:

{
  "aud": "no-api-key",
  "iat": 1511963669,
  "exp": 1511967269,
  "sub": "user-123",
  "user": {
    "email": "user@example.com",
    "name": "John Doe"
  },
  "auth": {
    "ai": {
      "permissions": [
        "ai:conversations:read",
        "ai:conversations:write",
        "ai:models:agent",
        "ai:actions:system:*",
        "ai:reviews:system:*"
      ]
    }
  }
}

Permissions

Permissions are specified in the auth.ai.permissions array within the JWT token and control which AI features, models, and capabilities users can access.

For a complete list of available permissions, permission examples, and best practices, see Permissions.

For complete details on all required claims, including types, formats, and implementation examples, see:

Signature

The signature is created by encoding the header and payload using Base64URL, then signing them with the private key using the specified algorithm. The TinyMCE AI service verifies the signature using the corresponding public key stored in the Tiny Account.

Supported Algorithms

TinyMCE does not support symmetrical encryption algorithms, such as HS256. Tiny recommends using the RS256 algorithm. The following algorithms are supported:

  • RS256

  • RS384

  • RS512

  • PS256

  • PS384

  • PS512

Requests to the Token Endpoint

The token for TinyMCE AI is requested by the TinyMCE AI plugin. The easiest way to configure this is to set the tinymceai_token_provider option to a function that fetches the token from the endpoint.

The token endpoint will be requested: * At editor initialization * Periodically to refresh the token (typically every hour)

Simple Usage

tinymce.init({
  selector: 'textarea',
  plugins: 'tinymceai',
  toolbar: 'tinymceai-chat tinymceai-quickactions tinymceai-review',
  tinymceai_token_provider: () => {
    return fetch('http://localhost:3000/jwt', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
    }).then(response => response.json());
  },
});

The editor will not be ready to use until the first token is obtained from the token endpoint. If an error occurs during the initial request, the editor will not start correctly.

Responses from the Token Endpoint

The token provider must return an object with a token property: { token: string }. The endpoint may respond in either format:

  • JSON response: Endpoint returns { "token": "eyJ..." }. Use response.json() and return { token: data.token }.

  • Plain text response: Endpoint returns the raw JWT string. Use response.text() and return { token }.

Example: JSON response
{
  "token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Example: Plain text response
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

Quick Setup

To set up JWT authentication for TinyMCE AI:

  1. Generate a public/private key pair and add the public key to the Tiny Account using Tiny Account - JWT Keys.

  2. Set up a JWT endpoint that generates tokens with the required claims.

  3. Configure TinyMCE to use the JWT endpoint through the tinymceai_token_provider option.

For step-by-step implementation instructions with complete code examples, see:

Tools

JWT tokens can be validated and debugged using the jwt.io debugger.

Troubleshooting

Invalid token

If an error message indicates an invalid token:

  • Verify that the token was created in accordance with the required claims and format

  • Ensure the API key in the aud claim is correct and valid

  • Verify that the token is signed with one of the supported algorithms

  • Check that the public key in the Tiny Account matches the private key used to sign the token

  • Validate the token structure using the jwt.io debugger

  • Ensure the iat (issued at) timestamp is correct and not in the future

  • Verify that system time is accurate (time drift can cause token validation issues)

Insufficient permissions

If an error indicates insufficient permissions:

  • Verify that the token includes the auth.ai.permissions array with the required permissions

  • Check that the permissions match the AI features being accessed

  • Review the Permissions guide for the correct permission format

  • Ensure permissions are specified correctly (for example, ai:conversations:read, ai:conversations:write)