Choose interaction capabilities and permissions

Choose instance actions, customize client-side decisions, and enforce authorization in your backend.

Start with your application's verified permissions. Use them to configure the Editor's available actions, then enforce the same policy at the trusted boundary where your application accepts changes.

Choose the layer

LayerUse it forWho owns the decision
interactionSet the actions this Editor instance allows, such as reading comments or deciding tracked changes.Your application configures client-side capabilities.
permissionResolverCustomize supported client-side checks for a particular comment, tracked change, or versioning action.Your synchronous callback overrides or preserves a built-in decision.
Trusted backendAuthorize document reads, saves, collaboration room access, and changes your service accepts.Your server verifies identity and enforces application policy.

Use ui to choose what SuperDoc renders. Hiding the comments panel with ui.comments: false does not remove comments or grant or revoke an action. Custom comments controls still need to respect available actions and handle the controller's result.

Set the instance capabilities

interaction.comments.level is the highest comment interaction level the instance allows. Levels are cumulative; specific actions can still be blocked by their permission checks or document state.

LevelAvailable comment actions before other checks
readRead existing threads.
writeRead, create, reply, edit, and delete.
resolveAll write actions, plus resolve and reopen. This is the default.

These levels also apply in documentMode: 'viewing'. The default resolve level allows comment creation, replies, editing your own comments and replies, deletion, and resolve/reopen when permission and command checks allow. Creating a comment from document text requires allowSelectionInViewMode: true. Your role and permissionResolver determine whether you can delete other authors' comments or resolve their threads. Viewing mode keeps document text read-only. For a viewer with read-only comments too, set interaction.comments.level: 'read'; see the read-only viewer configuration.

Comment levels do not control tracked-change decisions. Set interaction.trackedChanges.allowDecisions: false to block accept and reject in this instance. Its default is true; document mode and command availability can still block decisions. Choosing suggesting controls how new edits are recorded, not who may decide existing proposals.

For example, use write when contributors may discuss a passage but should not resolve its thread. Use resolve when reviewers may resolve threads, then use the resolver for supported checks that differ by author or action. See Review workflows for proposing changes without deciding them.

Customize a specific client-side check

Set permissionResolver at the top level of the Editor configuration. The callback is synchronous: return true or false to override a permission decision, or undefined to preserve defaultDecision. An async callback is not supported. The default uses the configured role and isInternal values.

The callback receives permission, role, isInternal, defaultDecision, comment, trackedChange, currentUser, and superdoc. Entity values may be null when the check has no corresponding entity. The configured browser user and role describe this client; they are not proof of authenticated identity.

In the Quickstart project, add these options alongside the existing document, user, and export configuration:

import type { Config } from 'superdoc';

export const permissionOptions = {
  interaction: {
    comments: { level: 'resolve' },
    trackedChanges: { allowDecisions: true },
  },
  permissionResolver: ({ permission }) => {
    switch (permission) {
      case 'COMMENTS_DELETE_OTHER':
      case 'REJECT_OTHER':
        return false;
      default:
        return undefined;
    }
  },
} satisfies Pick<Config, 'interaction' | 'permissionResolver'>;

This example keeps comment resolution available but denies deleting someone else's comment and rejecting someone else's tracked change. Other checks retain their built-in decision. In Vanilla, spread permissionOptions into new SuperDoc(); in React, spread it onto SuperDocEditor.

A resolver allowance cannot override an interaction restriction or make an unavailable action possible. A denied check can further restrict an action that the instance otherwise permits. For example, returning true for RESOLVE_OTHER does not make comment resolution available at level write.

Permission keys

These are the current permission constants. They do not mean every UI surface or programmatic method invokes every check. In particular, COMMENTS_OVERFLOW is the own-comment constant's literal value; it has no _OWN suffix.

KeysCheck
RESOLVE_OWN, RESOLVE_OTHERResolve or reopen a comment, or accept a tracked change, according to authorship.
REJECT_OWN, REJECT_OTHERReject a tracked change according to authorship.
COMMENTS_DELETE_OWN, COMMENTS_DELETE_OTHERDelete a comment according to authorship.
COMMENTS_OVERFLOW, COMMENTS_OVERFLOW_OTHERComment overflow permission constants; current built-in comment action availability checks the actions themselves.
UPLOAD_VERSION, VERSION_HISTORYVersioning permission constants; your versioning integration must apply its policy where it handles these actions.

For custom UI, check action availability and inspect mutation receipts. A generic permission check alone does not establish that an action can run. Direct Document API calls and headless operations are separate execution surfaces: do not assume permissionResolver intercepts every mutation. Authorize application-owned commands before invoking them. See Document API comments and custom review controls.

Enforce policy where changes are accepted

Both Editor mechanisms run in the browser and are not an authorization boundary. Someone who controls the client can change its configuration or send a request without using your buttons.

Your backend must verify the authenticated identity and document access before serving a document, accepting a save, or allowing a collaboration connection. Protect separate file endpoints as well as the room. Use Control room access for the collaboration connection example.

If your policy allows discussion but forbids changing document text, granting save access alone does not enforce that distinction. Accepting arbitrary DOCX uploads or unrestricted collaboration updates cannot guarantee comment-only changes. Your trusted service must validate the permitted changes or expose operations it can authorize individually. Choose a collaboration provider and persistence path that can enforce the policy you need.

Keep client settings aligned with that policy for a clear user experience. Do not treat a hidden button, a resolver result, or a browser-supplied author as evidence that the backend request is authorized.

Word restriction modes and named exceptions

editor.doc.protection.setEditingRestriction({ mode }) authors readOnly, comments, trackedChanges, or forms in the DOCX. Always inspect the returned state.editingRestriction.runtimeEnforced: V2 enforces readOnly; the other three modes are saved for Word and currently report false in SuperDoc. In particular, trackedChanges does not switch SuperDoc to suggesting mode; direct edits can be saved without revision markup. enforced: true describes the saved Word setting, not a browser authorization guarantee. Use clearEditingRestriction() to disable the saved restriction.

Your application owns the editor roster and authenticated user. The superdoc helpers accept that roster explicitly, so they work with Config.users, superdoc.users, or an application directory without treating presence or comment authors as a directory:

import { listPermissionRangeEditors, resolvePermissionRangeEditor } from 'superdoc';

const choices = listPermissionRangeEditors(superdoc.users);
const selected = resolvePermissionRangeEditor(superdoc.users, selectedUserId);
if (selected.status === 'resolved') {
  await editor.doc.permissionRanges.create({ target: selection, principal: selected.principal });
}

Discovery includes ambiguous entries so the host can disable conflicting choices. Resolution returns unknown for absent IDs and ambiguous for duplicate IDs, duplicate emails, or email/ID collisions; neither result contains a grant. Names are display labels. Resolution uses an exact host ID or a case-insensitive email and serializes the email into Word's w:ed when supplied. An ID without an email remains a host-specific Word editor string; it does not establish that Word recognizes the same account. Word account authentication remains external.

Set Config.user to the active host user. In a readOnly document, a well-formed permission range covering the full edit allows that user's exact id, their email ignoring case, or everyone. Overlapping grants are additive: a grant to another editor does not cancel a matching user or everyone grant. Users without a matching grant remain refused. This works without a permissionResolver; tracked-change author overrides do not change the active permission identity. Imported unsupported groups, missing or conflicting identities, and malformed markers block intersecting edits even when another range grants access. Body permissions are supported in collaboration; editing permission markers in headers and footers during collaboration remains unsupported.

Saved editor IDs and the host roster are different things. editor.doc.permissionRanges.list() reads document exceptions; the helpers resolve host identities and do not authenticate users, provision Word accounts, or change server access controls.

On this page