Revise Developer Platform menu

Roles and permissions

What a participant is allowed to do, enforced everywhere.

These docs are for version 2.3.x. See the latest version.

A mode is something the user switches between: editing or suggesting. A role limits what the user can do. It cannot be changed from inside the editor.

TSX
<ReviseEditor
  role="suggester"
  initialDocuments={[
    { id: "contract-1", source: file },
    { id: "exhibit-a", source: exhibit, role: "viewer" }, // per document
  ]}
/>
RoleEditsDirect editsAccept / rejectComments
editor (default)YesYesYesYes
suggesterAs tracked suggestions onlyNoNoYes
viewerNoNoNoNo

Why a suggester cannot accept#

Accepting a tracked change is an edit. If a suggester could accept their own suggestions, every change could skip review by someone else.

A suggester can still navigate review, preview accept and reject without changing the document, and comment.

Enforcement#

The role applies to every surface:

  • Typing and the toolbar. The document stays in a mode the role permits. setDocumentMode() clamps the requested mode: asking for "editing" as a suggester sets "suggesting". The onDocumentModeChange callback reports the resulting mode.
  • The built-in chrome. The mode toggle is hidden when the role has one mode. The ribbon shows review navigation without accept and reject. The inline accept and reject tooltip on each suggestion is hidden.
  • The handle. review.acceptCurrent(), acceptAll(), acceptSuggestions(), and the reject counterparts return false or a decision with every ID unresolved. Comment mutations do nothing for a viewer.
  • Agent tools. tools.execute() returns { ok: false, error: { code: "role_not_permitted" } } for a mutation a viewer cannot make, and for any directMode call from a suggester. A delegated agent.run() is checked before it starts and throws ReviseRoleError instead.
TypeScript
import { ReviseRoleError } from "@reviseio/editor";

const result = await editor.tools.execute("replace", input, { directMode: true });
if (!result.ok && result.error.code === "role_not_permitted") {
  // A suggester can't apply changes directly; without directMode, the same
  // call adds the edit as a suggestion.
}

try {
  await editor.agent.run(task, { directMode: true });
} catch (error) {
  if (error instanceof ReviseRoleError) {
    // error.role === "suggester", error.action === "apply changes directly"
  }
}

directMode applies a change without a tracked change, so a suggester cannot use it. Without directMode, the same tool call adds the edit as a suggestion.

Read the role#

TypeScript
editor.getRole();             // active document
editor.getRole("exhibit-a");  // a specific one

A role is a UI and API boundary, not a security control. It limits what this browser can do through the SDK. It does not authenticate anyone. In a shared room, each participant sets their own role. To make a role authoritative, your server must assign it and your transport must reject writes that violate it. Revise does not run a server here.