# Permissions

Permissions decide which models, file formats, actions, and reviews a user can use with CKEditor AI. You put them in the `auth.ai.permissions` claim of the JWT you issue to that user.

This page lists every scope, the wildcard rules, and the 403 error a missing scope produces. To build the token endpoint, see [Authentication](authentication.md).

<a id="permission-format">

## Permission format

Permissions are an array of strings in the token’s `auth.ai.permissions` claim. Each string has the form `ai:<type>:<value>`.

A trailing `*` matches every segment below it, at any depth. `ai:models:*` grants every model from every provider. A `*` inside a segment is a wildcard for that segment only. `ai:models:openai:gpt-4*` grants every OpenAI model with an id that starts with `gpt-4`.

> **Warning**
>
> Two scopes sign cleanly and grant nothing. The user gets a 403 on the first request instead of an error when you sign the token.
>
> * **A scope without a wildcard grants nothing below it:** `ai:models:openai` does not grant the OpenAI models. Use `ai:models:openai:*` instead.
> * **The type segment cannot be a wildcard:** `ai:*` is not a valid permission. The service drops it when it validates the token.

<a id="access-to-conversations-and-documents">

## Access to conversations and documents

Permissions decide which features a token may use. They do not grant access to a single conversation or document.

* **Conversations:** a user sees only the conversations they created. The `sub` of the token decides which ones.
* **Document Processing:** any token with `ai:documents:process` can send any document. Your backend decides who sends what.

<a id="permission-examples">

## Permission examples

Three tokens, from the narrowest to the widest. For the profiles most integrations start from, see [Set the user permissions](authentication.md#set-the-user-permissions).

<a id="basic-user">

### Basic user

A chat user on the Agent model who can attach PDF and DOCX files, and nothing else: no actions, no reviews, no images, and no URLs.

```json
{
  "auth": {
	"ai": {
	  "permissions": [
		"ai:conversations:read",
		"ai:conversations:write",
		"ai:models:agent",
		"ai:conversations:context:files:pdf",
		"ai:conversations:context:files:docx"
	  ]
	}
  }
}
```

<a id="restricted-user-review-only">

### Restricted user (review only)

A token that runs two system reviews and nothing else. A system review checks only its own scope, so the token needs no model scope.

```json
{
  "auth": {
	"ai": {
	  "permissions": [
		"ai:reviews:system:correctness",
		"ai:reviews:system:clarity"
	  ]
	}
  }
}
```

<a id="enterprise-admin">

### Enterprise admin

A backend token for managing contexts and MCP servers and reading usage. It satisfies every check, so never issue it to a browser or an end user.

```json
{
  "auth": {
	"ai": {
	  "permissions": [
		"ai:admin"
	  ]
	}
  }
}
```

<a id="scopes">

## Scopes

<a id="admin-permissions">

### Admin permissions

<a id="aiadmin">

#### `ai:admin`

Satisfies every permission check in the API.

Never issue an admin token to a browser or an end user. Call the admin endpoints from your backend only, and grant every other user the scopes in the sections below.

`ai:admin` is required for these operations:

* management of the [context library](extensions/context-library.md): contexts, prompts, and files,
* management of MCP server definitions,
* access to other users’ conversations: list, read, and delete,
* access to billing usage.

<a id="model-permissions">

### Model permissions

Model permissions decide which models a user can use, in every feature.

<a id="aimodels">

#### `ai:models:*`

Access to every model, including models added later.

<a id="aimodelsprovider">

#### `ai:models:<provider>:*`

Access to every model from one provider. Examples: `ai:models:openai:*`, `ai:models:anthropic:*`, `ai:models:google:*`.

<a id="aimodelsprovidermodel-name">

#### `ai:models:<provider>:<model-name>`

Access to one model. Examples: `ai:models:openai:gpt-5`, `ai:models:anthropic:claude-sonnet-5`. See [Models](models.md) for the model ids.

<a id="aimodelsagent">

#### `ai:models:agent`

Access to the Agent model. The Agent model selects a model for each request.

<a id="conversation-permissions">

### Conversation permissions

<a id="aiconversations">

#### `ai:conversations:*`

Access to every scope in this section and in “Conversation context permissions”.

<a id="aiconversationsread">

#### `ai:conversations:read`

Access to conversation history: the list of conversations and their messages.

<a id="aiconversationswrite">

#### `ai:conversations:write`

Lets the user send messages, and create, update, and delete conversations. These operations also check `ai:conversations:read`, so grant both.

<a id="aiconversationswebsearch">

#### `ai:conversations:websearch`

Access to web search in conversations and document processing calls.

<a id="aiconversationsreasoning">

#### `ai:conversations:reasoning`

Access to reasoning in conversations and document processing calls.

<a id="conversation-context-permissions">

### Conversation context permissions

Conversation context permissions decide which content a user can attach to a conversation.

<a id="aiconversationscontext">

#### `ai:conversations:context:*`

Access to every context source: all file formats and web URLs.

<a id="aiconversationscontextfiles">

#### `ai:conversations:context:files:*`

Access to every supported file format. The formats are listed below.

<a id="aiconversationscontextfilesformat">

#### `ai:conversations:context:files:<format>`

Access to one file format. One permission per format:

* `ai:conversations:context:files:pdf`
* `ai:conversations:context:files:docx`
* `ai:conversations:context:files:png`
* `ai:conversations:context:files:jpeg`
* `ai:conversations:context:files:txt`
* `ai:conversations:context:files:md`
* `ai:conversations:context:files:html`

<a id="aiconversationscontexturls">

#### `ai:conversations:context:urls`

Lets the user add web URLs as context.

<a id="documents-permissions">

### Documents permissions

<a id="aidocuments">

#### `ai:documents:*`

Access to every scope in this section.

<a id="aidocumentsprocess">

#### `ai:documents:process`

Lets the user run [document processing](document-processing.md) calls.

<a id="actions-permissions">

### Actions permissions

<a id="aiactions">

#### `ai:actions:*`

Access to custom and system actions.

<a id="aiactionscustom">

#### `ai:actions:custom`

Lets the user run custom actions with free-form prompts. The request also needs the scope of the model that the request names.

<a id="aiactionssystem">

#### `ai:actions:system:*`

Access to every system action.

<a id="aiactionssystemaction-name">

#### `ai:actions:system:<action-name>`

Access to one system action. Examples:

* `ai:actions:system:improve-writing`
* `ai:actions:system:fix-grammar`
* `ai:actions:system:translate`

<a id="reviews-permissions">

### Reviews permissions

<a id="aireviews">

#### `ai:reviews:*`

Access to custom and system reviews.

<a id="aireviewscustom">

#### `ai:reviews:custom`

Lets the user run custom reviews with free-form prompts. The request also needs the scope of the model that the request names.

<a id="aireviewssystem">

#### `ai:reviews:system:*`

Access to every system review.

<a id="aireviewssystemreview-name">

#### `ai:reviews:system:<review-name>`

Access to one system review. Examples:

* `ai:reviews:system:correctness`
* `ai:reviews:system:clarity`
* `ai:reviews:system:make-tone-professional`

<a id="context-library-permissions">

### Context library permissions

Context library permissions decide which contexts in the [context library](extensions/context-library.md) a user can use. Each permission names a context by its ID. The check runs wherever a request references a context: in conversations, in system actions, and in system reviews.

<a id="aicontexts">

#### `ai:contexts:*`

Access to every context in the library.

<a id="aicontextscontextid">

#### `ai:contexts:<contextId>`

Access to one context by its exact ID. Examples:

* `ai:contexts:product-docs`
* `ai:contexts:legal-guidelines`

<a id="aicontextspattern">

#### `ai:contexts:<pattern>`

Access to every context with an ID that matches a wildcard pattern. Examples:

* `ai:contexts:team-*` matches every context whose ID starts with `team-`.
* `ai:contexts:*-draft` matches every context whose ID ends with `-draft`.

<a id="recommendations">

## Recommendations

Start with the narrowest scopes that cover what your users do. Add scopes when a user needs them. Use wildcards for test environments and power users. For three starting profiles, see [Set the user permissions](authentication.md#set-the-user-permissions).

Do not use `ai:models:*` in production. It grants every model added later, and some of those cost more. Grant one provider, such as `ai:models:openai:*`, or exact models instead. The same rule applies to file formats. Grant the formats your users upload.

<a id="missing-permissions-error">

## Missing permissions error

If a token does not have a scope the endpoint needs, the API returns `403 Forbidden`. The body has the code `missing-permissions` and the message “The user is missing permissions”. The field `data.missingPermissions` lists the missing scopes.

To fix the error, add the listed scopes to the `auth.ai.permissions` claim in your token endpoint, issue a new token, and send the request again. See [Error codes](rest-api.md#error-codes) for the fields every error carries.

<a id="next-steps">

## Next steps

* **[Models](models.md)** lists the model ids the model permissions refer to.
* **[Conversations](conversations.md)**, **[Actions](actions.md)**, and **[Reviews](reviews.md)** each have a Permissions section with the scopes that feature needs.
* **[API reference](https://ai.cke-cs.com/v1/docs)** lists the scope each endpoint requires.

---

Full index of the Cloud Services documentation: [llms.txt](../../../llms.txt)
