Sign up (with export icon)

Authentication

Show the table of contents

Replace the development token from Quick start with a production setup: your own token endpoint, signed tokens, and permission profiles.

If you want a working example first, start with Quick start.

Note

Prerequisites

You need two values from your environment in the Customer Portal:

  • The environment ID. It goes into the aud claim of every token.
  • An access key. It signs the tokens. To create one, see Access key.

How tokens work

Copy link

Every request to CKEditor AI carries a JSON Web Token (JWT) as a bearer token, signed with your environment’s access key. The payload carries the claims that matter here:

  • aud is your environment ID, exactly as it appears in the Customer Portal.
  • sub is the ID of the user making the call.
  • exp keeps the token short-lived, minutes to hours.
  • auth.ai.permissions lists the user’s scopes. A misspelled scope is not rejected when the token is signed, and it grants nothing.

Build a token endpoint

Copy link

Your application issues the tokens. It authenticates the user, signs a short-lived JWT with your environment’s access key, and returns it to the client. Token endpoint covers how to build one, and there is working code for Node.js, Python, Java, PHP, and ASP.NET.

CKEditor AI adds one claim to that token, auth.ai.permissions. A payload for a user of the editor features looks like this:

{
	"aud": "<your environment ID>",
	"sub": "<your user ID>",
	"iat": 1735689600,
	"exp": 1735693200,
	"auth": {
		"ai": {
			"permissions": [
				"ai:conversations:read",
				"ai:conversations:write",
				"ai:models:agent"
			]
		}
	}
}
Copy code

Clients fetch a fresh token whenever they need one, so the short expiry costs them nothing.

Set the user permissions

Copy link

Permissions are an array of scopes. The scopes decide which features, models, and contexts the user can call with the token. Each scope is a string of the form ai:<type>:<value>. See Permissions for the full catalog, wildcard rules, and error responses.

Most integrations need one of three profiles:

End user: a person who uses AI features through your UI or the editor.

[
	"ai:conversations:read",
	"ai:conversations:write",
	"ai:actions:*",
	"ai:reviews:*",
	"ai:models:agent"
]
Copy code

Server-to-server: a backend job that edits documents with no user present.

[
	"ai:documents:process",
	"ai:models:agent"
]
Copy code

Admin: an operator who manages contexts, MCP servers, and other environment-level resources. The ai:admin scope satisfies every permission check.

[
	"ai:admin"
]
Copy code

Rotate keys

Copy link

An environment can hold several access keys at once, and a token signed with any of them is valid. To rotate a key:

  1. Create the new access key in the Customer Portal.
  2. Switch your token endpoint to the new key.
  3. Wait until the tokens signed with the old key have expired.
  4. Remove the old key.

See Access key for adding and removing keys in the Customer Portal.

Test a token

Copy link

Before you connect the token endpoint to your application, check that it works. These checks catch the most common mistakes.

Read the claims

Copy link

A JWT is not encrypted, so you can decode it and look at its contents. Paste it into jwt.io or run jwt decode <token> locally, and check the payload against the claims in How tokens work. The scopes are the usual mistake: auth.ai.permissions has to hold the ones you expect, spelled correctly.

Call the service

Copy link

Call the service with the token. Use the host for your environment’s region: https://ai.cke-cs.com for the US and https://ai.cke-cs-eu.com for the EU. Request the list of models first, because it has no LLM cost:

TOKEN=$(curl -s "<your-token-endpoint-url>")

# The US region host. For the EU region, use https://ai.cke-cs-eu.com
curl -s "https://ai.cke-cs.com/v1/models/1" \
	-H "Authorization: Bearer $TOKEN"
Copy code

Each model in the response has an allowed flag. The flag shows whether your token carries the ai:models:* scope for that model:

{
	"items": [
		{
			"id": "agent-1",
			"name": "Agent",
			"allowed": true
		}
	]
}
Copy code

If a model you expected to use returns "allowed": false, the token is valid but does not have that model’s scope. See Models for the full response.

When a scope is missing

Copy link

An endpoint returns 403 when your token does not carry a scope the endpoint needs. The response lists the missing scopes:

{
	"code": "missing-permissions",
	"message": "The user is missing permissions",
	"data": {
		"missingPermissions": [ "ai:models:agent" ]
	}
}
Copy code

Add the listed scopes to the auth.ai.permissions claim in your token endpoint, issue a new token, and send the request again.

Next steps

Copy link
  • Permissions lists every scope, the wildcard rules, and the error responses.
  • Security & compliance covers data flow, storage and retention, content moderation, and compliance attestations.