Permission Control

Univer provides permission control capabilities to restrict user operations on workbooks, worksheets, and ranges. When a user attempts an operation without the required permission, execution is halted and the user is notified. For example, you can protect a range to control whether collaborators can edit, view, copy, or filter within that range.

Your service must persist protection rules and collaborator changes, return the current user’s permissions, and propagate request failures. Empty mock lists are not a persistence implementation. In collaboration, the backend must independently check read, JOIN, and mutation permissions; see Identity and authorization. UI protection and hiding shadows do not replace server authorization.

Permission Service Integration

Choose a task below. Basic operations, advanced examples, configuration, and troubleshooting stay on this page; full API contracts are maintained in Reference.

Core Concepts

  • Scope: Permissions apply at three levels—workbook, worksheet, and range.
  • Permission Points: Each feature corresponds to a permission point. Modifying a point controls whether that feature is available.
  • Protection Rules: Before setting permission points for worksheets and ranges, you must create a protection rule.

Local, non-persistent permissions can be changed through permission points. For persistence, see Permission Service Integration

In a collaborative editing scenario, updating a permission point synchronizes the server state:

  • false: The permission point requires at least the owner role
  • true: The permission point requires at least the reader role

Basic Example

Replace user1 and user2 with real collaborator IDs returned by your authorization service before using the allowedUsers examples.

The most common permission setting methods are shown below at three levels: workbook, worksheet, and range.

Workbook Permissions Code Example

Workbook-level permissions can be set directly via the Facade API.

The following example disables editing for the entire workbook. For other functions, replace the permission point accordingly (see the workbook permission points list):

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// Set the workbook to be non-editableawait workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, false)

Key points:

  • Workbook permission points can be set directly without creating protection rules.

Worksheet Permissions Code Example

Worksheet and range permissions can be set via the Facade API or commands. The following example demonstrates how to set worksheet edit permissions. For other features, replace the permission point accordingly (see the worksheet permission points list):

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// Create worksheet protection, allow specified users to editconst permissionId = await worksheetPermission.protect({  allowedUsers: ['user1', 'user2'],  name: 'My Worksheet Protection',})// To set permission points, you must first protect the worksheetawait worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)

Delete Worksheet Permissions

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const worksheetPermission = fWorksheet.getWorksheetPermission()// Remove worksheet protectionawait worksheetPermission.unprotect()

Custom Range Permissions Code Example

Range permissions can also be set via API and command modes. Here, we'll use range edit permissions as an example. Other range functions require replacing the permission points, see the list of permission points - Range for details.

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')const rangePermission = fRange.getRangePermission()// Set range protection permission, allow specified users to edit but not allow others to viewconst rule = await rangePermission.protect({  name: 'My protected range',  allowViewByOthers: false,  allowedUsers: ['user1', 'user2'],})console.log(rule)// To set permission points, you must first create a range protection rule.await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)

Delete Range Protection Permissions

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const fRange = fWorksheet.getRange('A1:B2')const rangePermission = fRange.getRangePermission()// delete all rules within the rangeawait rangePermission.unprotect()// Or delete specific rules within the rangeconst rules = await rangePermission.listRules()if (rules.length > 0) {  await rules[0].remove()}

Common tasks

Set a workbook to read-only

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getWorkbookPermission()await permission.setMode('viewer')console.log(permission.getSnapshot())

Manage protected ranges

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const fWorksheet = fWorkbook.getActiveSheet()const permission = fWorksheet.getWorksheetPermission()const createdRules = await permission.protectRanges([  {    ranges: [fWorksheet.getRange('A1:B2')],    options: { name: 'Public area', allowViewByOthers: true },  },  {    ranges: [fWorksheet.getRange('C3:D4')],    options: { name: 'Private area', allowViewByOthers: false, allowedUsers: ['user1'] },  },])console.log(createdRules)const rules = await permission.listRangeProtectionRules()const firstRule = rules[0]if (firstRule) {  await firstRule.updateRanges([fWorksheet.getRange('A1:B3')])}

Diagnose cell permissions

TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const permission = fWorkbook.getActiveSheet().getWorksheetPermission()console.log(permission.debugCellPermission(0, 0))

List of permission points

You can view the source code for all permission points here.

When workbook permissions overlap with worksheet or range permissions, all relevant permissions must be set to true for the feature to be usable.

Workbook Permissions

API EnumCorresponding Permission Point ClassDescription
univerAPI.Enum.WorkbookPermissionPoint.EditWorkbookEditablePermissionCan edit
univerAPI.Enum.WorkbookPermissionPoint.ViewWorkbookViewPermissionCan view
univerAPI.Enum.WorkbookPermissionPoint.PrintWorkbookPrintPermissionCan print
univerAPI.Enum.WorkbookPermissionPoint.ExportWorkbookExportPermissionCan export
univerAPI.Enum.WorkbookPermissionPoint.ShareWorkbookSharePermissionCan share
univerAPI.Enum.WorkbookPermissionPoint.CopyContentWorkbookCopyPermissionCan copy
univerAPI.Enum.WorkbookPermissionPoint.DuplicateFileWorkbookDuplicatePermissionCan duplicate
univerAPI.Enum.WorkbookPermissionPoint.CommentWorkbookCommentPermissionCan comment
univerAPI.Enum.WorkbookPermissionPoint.ManageCollaboratorWorkbookManageCollaboratorPermissionCan manage collaborators
univerAPI.Enum.WorkbookPermissionPoint.CreateSheetWorkbookCreateSheetPermissionCan create worksheets
univerAPI.Enum.WorkbookPermissionPoint.DeleteSheetWorkbookDeleteSheetPermissionCan delete worksheets
univerAPI.Enum.WorkbookPermissionPoint.RenameSheetWorkbookRenameSheetPermissionCan rename worksheets
univerAPI.Enum.WorkbookPermissionPoint.MoveSheetWorkbookMoveSheetPermissionCan move worksheets
univerAPI.Enum.WorkbookPermissionPoint.HideSheetWorkbookHideSheetPermissionCan hide worksheets
univerAPI.Enum.WorkbookPermissionPoint.CopySheetWorkbookCopySheetPermissionCan copy worksheets
univerAPI.Enum.WorkbookPermissionPoint.ViewHistoryWorkbookViewHistoryPermissionCan view history
univerAPI.Enum.WorkbookPermissionPoint.RecoverHistoryWorkbookRecoverHistoryPermissionCan recover history
univerAPI.Enum.WorkbookPermissionPoint.CreateProtectionWorkbookCreateProtectPermissionCan create protection
univerAPI.Enum.WorkbookPermissionPoint.InsertRowWorkbookInsertRowPermissionCan insert rows
univerAPI.Enum.WorkbookPermissionPoint.InsertColumnWorkbookInsertColumnPermissionCan insert columns
univerAPI.Enum.WorkbookPermissionPoint.DeleteRowWorkbookDeleteRowPermissionCan delete rows
univerAPI.Enum.WorkbookPermissionPoint.DeleteColumnWorkbookDeleteColumnPermissionCan delete columns

Worksheet Permissions

API EnumCorresponding Permission Point ClassDescription
univerAPI.Enum.WorksheetPermissionPoint.EditWorksheetEditPermissionCan edit
univerAPI.Enum.WorksheetPermissionPoint.ViewWorksheetViewPermissionCan view
univerAPI.Enum.WorksheetPermissionPoint.CopyWorksheetCopyPermissionCan copy
univerAPI.Enum.WorksheetPermissionPoint.SetCellValueWorksheetSetCellValuePermissionCan edit cell values
univerAPI.Enum.WorksheetPermissionPoint.SetCellStyleWorksheetSetCellStylePermissionCan edit cell styles
univerAPI.Enum.WorksheetPermissionPoint.SetRowStyleWorksheetSetRowStylePermissionCan set row styles
univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyleWorksheetSetColumnStylePermissionCan set column styles
univerAPI.Enum.WorksheetPermissionPoint.InsertRowWorksheetInsertRowPermissionCan insert rows
univerAPI.Enum.WorksheetPermissionPoint.InsertColumnWorksheetInsertColumnPermissionCan insert columns
univerAPI.Enum.WorksheetPermissionPoint.DeleteRowWorksheetDeleteRowPermissionCan delete rows
univerAPI.Enum.WorksheetPermissionPoint.DeleteColumnWorksheetDeleteColumnPermissionCan delete columns
univerAPI.Enum.WorksheetPermissionPoint.SortWorksheetSortPermissionCan sort
univerAPI.Enum.WorksheetPermissionPoint.FilterWorksheetFilterPermissionCan filter
univerAPI.Enum.WorksheetPermissionPoint.PivotTableWorksheetPivotTablePermissionCan use pivot tables
univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlinkWorksheetInsertHyperlinkPermissionCan use hyperlinks
univerAPI.Enum.WorksheetPermissionPoint.ManageCollaboratorWorksheetManageCollaboratorPermissionCan manage collaborators
univerAPI.Enum.WorksheetPermissionPoint.DeleteProtectionWorksheetDeleteProtectionPermissionCan delete protection
univerAPI.Enum.WorksheetPermissionPoint.EditExtraObjectWorksheetEditExtraObjectPermissionCan edit extra objects
univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCellsWorksheetSelectProtectedCellsPermissionCan select protected cells
univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCellsWorksheetSelectUnProtectedCellsPermissionCan select unprotected cells

Range Protection

API EnumCorresponding Permission Point ClassDescription
univerAPI.Enum.RangePermissionPoint.EditRangeProtectionPermissionEditPointCan edit protected ranges
univerAPI.Enum.RangePermissionPoint.ViewRangeProtectionPermissionViewPointCan view content of protected ranges
univerAPI.Enum.RangePermissionPoint.DeleteRangeProtectionPermissionDeleteProtectionPointCan delete protected ranges
univerAPI.Enum.RangePermissionPoint.ManageCollaboratorRangeProtectionPermissionManageCollaPointCan manage collaborators for protected ranges

Permission UI Configuration

Protected Range Shadow Strategy

To distinguish protected areas that the current user can edit from those they cannot, use non-editable. Editable protected areas have no shadow; protected areas with editing disabled keep their shadow. Non-viewable protected ranges remain masked.

This setting controls the display of range and worksheet protection. It does not create protection rules or change edit/view permissions, and it does not add shadows to unprotected areas. Configure the protection rules and the current user's permissions first, as shown above.

StrategyDisplay behavior
true / 'always'Show shadows for all protected areas (default).
'non-editable'Hide shadows on editable protected areas; keep them on non-editable areas.
'non-viewable'Show shadows only on non-viewable protected areas.
false / 'none'Hide all protection shadows; permission checks still apply.

Protection shadow preview

Compare the same areas under different strategies for the current user.

Unprotected

A1:B3

No shadow

Protected · editable

D1:E3

No shadow

Protected · read-only

G1:H3

Shadow shown

Protected · not viewable

J1:K3

Shadow shown

protectedRangeShadow: 'non-editable'

Illustration only: changing the shadow does not change permissions. Hidden content stays hidden, even with none.

Set the strategy during initialization:

TypeScript
univer.registerPlugin(UniverSheetsUIPlugin, {  protectedRangeShadow: 'non-editable',})

You can also modify it dynamically via the API:

The Facade API below updates existing workbooks in the current Univer instance. In plugin mode, first import @univerjs/sheets-ui/facade; the Sheets Core preset already includes it.

TypeScript
// Set to only show shadows for non-editable rangesuniverAPI.setProtectedRangeShadowStrategy('non-editable')// Get the current protected range shadow display strategyconsole.log(univerAPI.getProtectedRangeShadowStrategy())// Subscribe to changes in the protected range shadow strategyconst subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {  console.log('Global strategy changed to:', strategy)  // Update UI or perform other actions})// Later, unsubscribe to clean upsubscription.unsubscribe()

Custom User Component

Univer's built-in user selector has limited flexibility. For more complex scenarios, you can provide a custom component as shown below.

You can refer to Custom Components for how to create custom components.

TypeScript
univer.registerPlugin(UniverSheetsUIPlugin, {  protectedRangeUserSelector: {    /**     * Custom component; must implement the `IPermissionDetailUserPartProps` interface.     */    component: CustomPermissionDetailUserPart,    /**     * The framework of the component. Must be passed correctly.     */    framework: 'react',  },})

Call setSelectUserList() from your picker’s change handler. This minimal React example clears the selection; useDependency runs inside the component and the service update runs only after a click. Implement the rest of your picker using IPermissionDetailUserPartProps.

TSX
import type { IPermissionDetailUserPartProps } from '@univerjs/sheets-ui'import type { FC } from 'react'import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'import { useDependency } from '@univerjs/ui'export const CustomPermissionDetailUserPart: FC<IPermissionDetailUserPartProps> = () => {  const service = useDependency(SheetPermissionUserManagerService)  const clearSelection = () => service.setSelectUserList([])  return <button type="button" onClick={clearSelection}>Clear selected users</button>}

Hide the Permission Dialog

TypeScript
univerAPI.setPermissionDialogVisible(false)

Permission Service Integration

Extended usage

When you need to check permissions in your own plugin, you can manipulate the permission points directly.

The following example uses WorkbookEditablePermission to demonstrate how to check permissions in your own plugin. Other permission points work similarly.

TypeScript
import { IPermissionService } from '@univerjs/core'import { WorkbookEditablePermission } from '@univerjs/sheets'class YourService {  constructor(@IPermissionService private _permissionService: IPermissionService) {  }  setWorkbookNotEditable() {    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false)  }  setWorkbookEditable() {    this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true)  }}

List of permission points

How to Extend Permission Points

To customize permission points, implement IPermissionPoint and register it with the permission service:

TypeScript
import type { IPermissionPoint } from '@univerjs/core'import { IPermissionService, PermissionStatus } from '@univerjs/core'import { UnitAction, UnitObject } from '@univerjs/protocol'export class CustomPermissionPoint implements IPermissionPoint {  type = UnitObject.Unkonwn // your type  subType = UnitAction.View // your subType  status = PermissionStatus.INIT  value = true // Default value  id: string  constructor(unitId: string, subUnitId: string, customId: string) {    // The id must be unique within `IPermissionService`.    this.id = `${unitId}.${subUnitId}.${customId}`  }}class YourService {  constructor(@IPermissionService private _permissionService: IPermissionService) {    this._init()  }  _init() {    this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id'))  }}// How to use it elsewhereclass ConsumeService {  constructor(@IPermissionService private _permissionService: IPermissionService) {  }  doSomething() {    const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)    console.log(point?.value)  }  bindEvent() {    // This returns an RxJS observable that lets you listen for permission changes    const point$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId', 'subUnitId', 'my-id').id)    console.log(point$)  }}

Integrating a Third-Party Authorization Service (Advanced)

Implement IAuthzIoService in your application and connect its permission, role, and collaborator methods to your backend. The example assumes that ./authorization-service exports this implementation as YourAuthzService. Register it before creating workbooks; keep the other initialization options and plugin registrations.

TypeScript
import { IAuthzIoService, Univer } from '@univerjs/core'import { YourAuthzService } from './authorization-service'const univer = new Univer({  override: [[IAuthzIoService, { useClass: YourAuthzService }]],})

Your service must persist protection rules and collaborator changes, return the current user’s permissions, and propagate request failures. Empty mock lists are not a persistence implementation. In collaboration, the backend must independently check read, JOIN, and mutation permissions; see Identity and authorization. UI protection and hiding shadows do not replace server authorization.

Collaborator Management

Collaborator management belongs to your application and permission service. Connect your user/ACL model and enforce server-side read, JOIN, and edit policies; see identity and authorization. The frontend APIs below require a matching permission-service implementation and do not automatically configure server authorization.

  • Get Collaborators List
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()const collaborators = await workbookPermission.listCollaborators()console.log(collaborators)
  • Add Collaborators
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// Add multiple collaborators at onceawait workbookPermission.setCollaborators([  {    user: { userID: 'user1', name: 'John Doe', avatar: 'https://...' },    role: univerAPI.Enum.UnitRole.Editor,  },  {    user: { userID: 'user2', name: 'Jane Smith', avatar: '' },    role: univerAPI.Enum.UnitRole.Reader,  },])// Add a single collaboratorawait workbookPermission.addCollaborator(  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },  univerAPI.Enum.UnitRole.Editor,)
  • Update collaborator role
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()await workbookPermission.updateCollaborator(  { userID: 'user1', name: 'John Doe Updated', avatar: 'https://...' },  univerAPI.Enum.UnitRole.Reader,)
  • Remove collaborators
TypeScript
const fWorkbook = univerAPI.getActiveWorkbook()if (!fWorkbook) throw new Error('No active workbook')const workbookPermission = fWorkbook.getWorkbookPermission()// Remove multiple collaboratorsawait workbookPermission.removeCollaborators(['user1', 'user2'])// Remove a single collaboratorawait workbookPermission.removeCollaborator('user1')

Reference

How is this guide?

© 2026 DreamNum Co., Ltd.