# Permission Control

- Human documentation: [https://docs.univer.ai/guides/sheets/features/core/permission](https://docs.univer.ai/guides/sheets/features/core/permission)

- Agent Markdown: [https://docs.univer.ai/guides/sheets/features/core/permission.md](https://docs.univer.ai/guides/sheets/features/core/permission.md)

- Requested language: `en-US`

- Content language: `en-US`

- Documentation version: `1.0.0-rc.0`

- Source: [sheets/features/core/permission.mdx](https://github.com/dream-num/documentation/blob/dev/content/guides/sheets/features/core/permission.mdx)

---

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.

> [!WARNING: Precautions before use]
> Univer provides extensible foundational capabilities, not out-of-the-box customized features.
> If you need persistence, organizational structures, or other tailored requirements, you must implement the storage of permission rules and integrate organizational structures yourself—typically through custom plugins.
> Therefore, it is normal to find the permission list empty or user information missing after setting permissions. This data must be fetched via your own API requests, which is custom logic you need to implement. Refer to the third-party integration section below for details.

> Interactive example: [Open the playground](/playground/sheets/permission)

## 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.

> [!INFO: Permission Point Explanation]
> In a local, non-persistent environment (without collaborative editing), you can control permissions directly by modifying permission points. For persistent permissions, refer to the "Integrating a Third-Party Authorization Service" section below.
> 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

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](https://docs.univer.ai/guides/sheets/getting-started/facade.md).

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

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Set the workbook to be non-editable
await 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](#worksheet-point)):

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Create worksheet protection, allow specified users to edit
const permissionId = await worksheetPermission.protect({
  allowedUsers: ['user1', 'user2'],
  name: 'My Worksheet Protection',
})

// To set permission points, you must first protect the worksheet
await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.Edit, false)
```

#### Delete Worksheet Permissions

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Remove worksheet protection
await 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](#range-point) for details.

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
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 view
const 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()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// delete all rules within the range
await rangePermission.unprotect()

// Or delete specific rules within the range
const rules = await rangePermission.listRules()
if (rules.length > 0) {
  await rules[0].remove()
}
```

## 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)
  }
}
```

You can also extend and modify other permission points to control different features. See the full list at the bottom of this page.

### 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 elsewhere
class 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)

> [!WARNING: Caution]
> It is recommended to avoid mixing custom permission access with the Permission Facade API, as it allows for more granular control over permission points.

The logic for determining permissions is typically handled by an external service, which involves a communication process. In the frontend SDK implementation, we use the [AuthzIoLocalService](https://github.com/dream-num/univer/blob/dev/packages/core/src/services/authz-io/authz-io-local.service.ts) to handle this logic.

In a production environment, we need to replace this implementation with a backend service. The frontend needs to implement the corresponding request functions based on the [IAuthzIoService](https://github.com/dream-num/univer/blob/dev/packages/core/src/services/authz-io/type.ts) interface for runtime replacement.

![Permission](https://raw.githubusercontent.com/dream-num/documentation/dev/content/guides/sheets/features/core/permission/permission-en.png)

Here is a simple example demonstrating the addition and deletion of protected range permissions for two predefined roles (Owner/Reader). The Owner has editing/viewing permissions for protected ranges, while the Reader cannot edit or view the contents of cells within protected ranges.

```typescript
import type { Injector } from '@univerjs/core'
import type { IActionInfo, IAllowedRequest, IBatchAllowedResponse, ICollaborator, ICreateRequest, ICreateRequest_SelectRangeObject, IListPermPointRequest, IPermissionPoint, IPutCollaboratorsRequest, IUnitRoleKV, IUpdatePermPointRequest } from '@univerjs/protocol'
import { createDefaultUser, generateRandomId, IAuthzIoService, Inject, IResourceManagerService, isDevRole, Univer, UserManagerService } from '@univerjs/core'
import { ObjectScope, UnitAction, UnitObject, UnitRole, UniverType } from '@univerjs/protocol'

class YourAuthzService implements IAuthzIoService {
  private _permissionMap: Map<string, ICreateRequest_SelectRangeObject & { objectType: UnitObject }> = new Map([])

  constructor(
    @IResourceManagerService private _resourceManagerService: IResourceManagerService,
    @Inject(UserManagerService) private _userManagerService: UserManagerService,
  ) {
    this._initSnapshot()
    this._initDefaultUser()
  }

  private _initDefaultUser() {
    const currentUser = this._userManagerService.getCurrentUser()
    const currentUserIsValid = currentUser && currentUser.userID
    if (!currentUserIsValid) {
      this._userManagerService.setCurrentUser(createDefaultUser(UnitRole.Owner))
    }
  }

  private _getRole(type: UnitRole) {
    const user = this._userManagerService.getCurrentUser()
    if (!user) {
      return false
    }
    return isDevRole(user.userID, type)
  }

  private _initSnapshot() {
    this._resourceManagerService.registerPluginResource({
      toJson: (_unitId: string) => {
        const obj = [...this._permissionMap.keys()].reduce((r, k) => {
          const v = this._permissionMap.get(k)
          r[k] = v!
          return r
        }, {} as Record<string, ICreateRequest_SelectRangeObject & { objectType: UnitObject }>)
        return JSON.stringify(obj)
      },
      parseJson: (json: string) => {
        return JSON.parse(json)
      },
      pluginName: 'SHEET_AuthzIoMockService_PLUGIN',
      businesses: [UniverType.UNIVER_SHEET, UniverType.UNIVER_DOC, UniverType.UNIVER_SLIDE],
      onLoad: (_unitId, resource) => {
        for (const key in resource) {
          this._permissionMap.set(key, resource[key])
        }
      },
      onUnLoad: () => {
        this._permissionMap.clear()
      },
    })
  }

  async create(config: ICreateRequest): Promise<string> {
    const permissionId = generateRandomId(8)
    if (config.objectType === UnitObject.SelectRange && config.selectRangeObject) {
      this._permissionMap.set(permissionId, { ...config.selectRangeObject, objectType: config.objectType })
    }
    return permissionId
  }

  async batchAllowed(config: IAllowedRequest[]): Promise<IBatchAllowedResponse['objectActions']> {
    const selectionRangeConfig = config.filter(c => c.objectType === UnitObject.SelectRange)
    if (selectionRangeConfig.length) {
      const currentUser = this._userManagerService.getCurrentUser()
      const res = [] as IBatchAllowedResponse['objectActions']
      selectionRangeConfig.forEach((c) => {
        res.push({
          unitID: c.unitID,
          objectID: c.objectID,
          actions: c.actions.map((action) => {
            if (isDevRole(currentUser.userID, UnitRole.Owner)) {
              return { action, allowed: true }
            }
            return { action, allowed: false }
          }),
        })
      })
      return res
    }
    return Promise.resolve([])
  }

  async list(config: IListPermPointRequest): Promise <IPermissionPoint[]> {
    const result: IPermissionPoint[] = []
    config.objectIDs.forEach((objectID) => {
      const rule = this._permissionMap.get(objectID)
      if (rule) {
        const item = {
          objectID,
          unitID: config.unitID,
          objectType: rule!.objectType,
          name: rule!.name,
          shareOn: false,
          shareRole: UnitRole.Owner,
          shareScope: -1,
          scope: {
            read: ObjectScope.AllCollaborator,
            edit: ObjectScope.AllCollaborator,
          },
          creator: createDefaultUser(UnitRole.Owner),
          strategies: [
            {
              action: UnitAction.View,
              role: UnitRole.Owner,
            },
            {
              action: UnitAction.Edit,
              role: UnitRole.Owner,
            },
          ],
          actions: config.actions.map((a) => {
            return { action: a, allowed: this._getRole(UnitRole.Owner) }
          }),
        }
        result.push(item)
      }
    })
    return result
  }

  async listCollaborators(): Promise<ICollaborator[]> {
    // List the existing collaborators
    return []
  }

  async allowed(_config: IAllowedRequest): Promise<IActionInfo[]> {
    // Because this is a mockService for handling permissions, we will not write real logic in it. We will only return an empty array to ensure that the permissions originally set by the user are not modified.
    // If you want to achieve persistence of permissions, you can modify the logic here.
    return Promise.resolve([])
  }

  async listRoles(): Promise<{ roles: IUnitRoleKV[], actions: UnitAction[] }> {
    return {
      roles: [],
      actions: [],
    }
  }

  async update(config: IUpdatePermPointRequest): Promise<void> {
    // Update bit information
  }

  async updateCollaborator(): Promise<void> {
    // Update collaborator information
    return undefined
  }

  async createCollaborator(): Promise<void> {
    // Create new collaborator information
    return undefined
  }

  async deleteCollaborator(): Promise<void> {
    return undefined
  }

  async putCollaborators(config: IPutCollaboratorsRequest): Promise<void> {
    return undefined
  }
}

export class YourPlugin extends Plugin {
  constructor(
    _config: unknown,
    @Inject(Injector) protected override _injector: Injector,
  ) {
  }

  override onStarting(): void {
    this._injector.add([IAuthzIoService, { useClass: YourAuthzService }])
  }
}

// By setting the override option to [[IAuthzIoService, null]], you can instruct Univer not to register the built-in IAuthzIoService.
// This way, Univer will use the service provided by YourAuthzService as the implementation of the authorization service.
const univer = new Univer({
  override: [[IAuthzIoService, null]],
})

univer.registerPlugin(YourPlugin)
```

## List of permission points

You can view the source code for all permission points [here](https://github.com/dream-num/univer/tree/dev/packages/sheets/src/services/permission/permission-point).

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 Enum                                                  | Corresponding Permission Point Class | Description              |
| --------------------------------------------------------- | ------------------------------------ | ------------------------ |
| univerAPI.Enum.WorkbookPermissionPoint.Edit               | WorkbookEditablePermission           | Can edit                 |
| univerAPI.Enum.WorkbookPermissionPoint.View               | WorkbookViewPermission               | Can view                 |
| univerAPI.Enum.WorkbookPermissionPoint.Print              | WorkbookPrintPermission              | Can print                |
| univerAPI.Enum.WorkbookPermissionPoint.Export             | WorkbookExportPermission             | Can export               |
| univerAPI.Enum.WorkbookPermissionPoint.Share              | WorkbookSharePermission              | Can share                |
| univerAPI.Enum.WorkbookPermissionPoint.CopyContent        | WorkbookCopyPermission               | Can copy                 |
| univerAPI.Enum.WorkbookPermissionPoint.DuplicateFile      | WorkbookDuplicatePermission          | Can duplicate            |
| univerAPI.Enum.WorkbookPermissionPoint.Comment            | WorkbookCommentPermission            | Can comment              |
| univerAPI.Enum.WorkbookPermissionPoint.ManageCollaborator | WorkbookManageCollaboratorPermission | Can manage collaborators |
| univerAPI.Enum.WorkbookPermissionPoint.CreateSheet        | WorkbookCreateSheetPermission        | Can create worksheets    |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteSheet        | WorkbookDeleteSheetPermission        | Can delete worksheets    |
| univerAPI.Enum.WorkbookPermissionPoint.RenameSheet        | WorkbookRenameSheetPermission        | Can rename worksheets    |
| univerAPI.Enum.WorkbookPermissionPoint.MoveSheet          | WorkbookMoveSheetPermission          | Can move worksheets      |
| univerAPI.Enum.WorkbookPermissionPoint.HideSheet          | WorkbookHideSheetPermission          | Can hide worksheets      |
| univerAPI.Enum.WorkbookPermissionPoint.CopySheet          | WorkbookCopySheetPermission          | Can copy worksheets      |
| univerAPI.Enum.WorkbookPermissionPoint.ViewHistory        | WorkbookViewHistoryPermission        | Can view history         |
| univerAPI.Enum.WorkbookPermissionPoint.RecoverHistory     | WorkbookRecoverHistoryPermission     | Can recover history      |
| univerAPI.Enum.WorkbookPermissionPoint.CreateProtection   | WorkbookCreateProtectPermission      | Can create protection    |
| univerAPI.Enum.WorkbookPermissionPoint.InsertRow          | WorkbookInsertRowPermission          | Can insert rows          |
| univerAPI.Enum.WorkbookPermissionPoint.InsertColumn       | WorkbookInsertColumnPermission       | Can insert columns       |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteRow          | WorkbookDeleteRowPermission          | Can delete rows          |
| univerAPI.Enum.WorkbookPermissionPoint.DeleteColumn       | WorkbookDeleteColumnPermission       | Can delete columns       |

### Worksheet Permissions

| API Enum                                                       | Corresponding Permission Point Class      | Description                  |
| -------------------------------------------------------------- | ----------------------------------------- | ---------------------------- |
| univerAPI.Enum.WorksheetPermissionPoint.Edit                   | WorksheetEditPermission                   | Can edit                     |
| univerAPI.Enum.WorksheetPermissionPoint.View                   | WorksheetViewPermission                   | Can view                     |
| univerAPI.Enum.WorksheetPermissionPoint.Copy                   | WorksheetCopyPermission                   | Can copy                     |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellValue           | WorksheetSetCellValuePermission           | Can edit cell values         |
| univerAPI.Enum.WorksheetPermissionPoint.SetCellStyle           | WorksheetSetCellStylePermission           | Can edit cell styles         |
| univerAPI.Enum.WorksheetPermissionPoint.SetRowStyle            | WorksheetSetRowStylePermission            | Can set row styles           |
| univerAPI.Enum.WorksheetPermissionPoint.SetColumnStyle         | WorksheetSetColumnStylePermission         | Can set column styles        |
| univerAPI.Enum.WorksheetPermissionPoint.InsertRow              | WorksheetInsertRowPermission              | Can insert rows              |
| univerAPI.Enum.WorksheetPermissionPoint.InsertColumn           | WorksheetInsertColumnPermission           | Can insert columns           |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteRow              | WorksheetDeleteRowPermission              | Can delete rows              |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteColumn           | WorksheetDeleteColumnPermission           | Can delete columns           |
| univerAPI.Enum.WorksheetPermissionPoint.Sort                   | WorksheetSortPermission                   | Can sort                     |
| univerAPI.Enum.WorksheetPermissionPoint.Filter                 | WorksheetFilterPermission                 | Can filter                   |
| univerAPI.Enum.WorksheetPermissionPoint.PivotTable             | WorksheetPivotTablePermission             | Can use pivot tables         |
| univerAPI.Enum.WorksheetPermissionPoint.InsertHyperlink        | WorksheetInsertHyperlinkPermission        | Can use hyperlinks           |
| univerAPI.Enum.WorksheetPermissionPoint.ManageCollaborator     | WorksheetManageCollaboratorPermission     | Can manage collaborators     |
| univerAPI.Enum.WorksheetPermissionPoint.DeleteProtection       | WorksheetDeleteProtectionPermission       | Can delete protection        |
| univerAPI.Enum.WorksheetPermissionPoint.EditExtraObject        | WorksheetEditExtraObjectPermission        | Can edit extra objects       |
| univerAPI.Enum.WorksheetPermissionPoint.SelectProtectedCells   | WorksheetSelectProtectedCellsPermission   | Can select protected cells   |
| univerAPI.Enum.WorksheetPermissionPoint.SelectUnProtectedCells | WorksheetSelectUnProtectedCellsPermission | Can select unprotected cells |

### Range Protection

| API Enum                                               | Corresponding Permission Point Class           | Description                                   |
| ------------------------------------------------------ | ---------------------------------------------- | --------------------------------------------- |
| univerAPI.Enum.RangePermissionPoint.Edit               | RangeProtectionPermissionEditPoint             | Can edit protected ranges                     |
| univerAPI.Enum.RangePermissionPoint.View               | RangeProtectionPermissionViewPoint             | Can view content of protected ranges          |
| univerAPI.Enum.RangePermissionPoint.Delete             | RangeProtectionPermissionDeleteProtectionPoint | Can delete protected ranges                   |
| univerAPI.Enum.RangePermissionPoint.ManageCollaborator | RangeProtectionPermissionManageCollaPoint      | Can manage collaborators for protected ranges |

## Configuration

### Protected Range Shadow Strategy

The protected range shadow is shown by default. You can hide it with the following configuration:

#### Preset Mode

```typescript
createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        /**
         * Strategy for showing the protected range shadow.
         * - true or 'always': Show shadow for all protected ranges (default behavior)
         * - 'non-editable': Only show shadow for ranges that cannot be edited (Edit permission is false)
         * - 'non-viewable': Only show shadow for ranges that cannot be viewed (View permission is false)
         * - false or 'none': Never show shadow for protected ranges
         * @default true
         */
        protectedRangeShadow: false,
      },
    }),
  ],
})
```

#### Plugin Mode

```typescript
univer.registerPlugin(UniverSheetsUIPlugin, {
  /**
   * Strategy for showing the protected range shadow.
   * - true or 'always': Show shadow for all protected ranges (default behavior)
   * - 'non-editable': Only show shadow for ranges that cannot be edited (Edit permission is false)
   * - 'non-viewable': Only show shadow for ranges that cannot be viewed (View permission is false)
   * - false or 'none': Never show shadow for protected ranges
   * @default true
   */
  protectedRangeShadow: false,
})
```

You can also modify it dynamically via the API:

```typescript
// Set to only show shadows for non-editable ranges
univerAPI.setProtectedRangeShadowStrategy('non-editable')

// Get the current protected range shadow display strategy
console.log(univerAPI.getProtectedRangeShadowStrategy())

// Subscribe to changes in the protected range shadow strategy
const subscription = univerAPI.getProtectedRangeShadowStrategy$().subscribe((strategy) => {
  console.log('Global strategy changed to:', strategy)
  // Update UI or perform other actions
})

// Later, unsubscribe to clean up
subscription.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.

> [!NOTE]
> You can refer to [Custom Components](https://docs.univer.ai/guides/sheets/ui/components.md) for how to create custom components.

#### Preset Mode

```typescript
const { univer } = createUniver({
  presets: [
    UniverSheetsCorePreset({
      sheets: {
        protectedRangeUserSelector: {
        /**
         * Custom component; must implement the `IPermissionDetailUserPartProps` interface.
         */
          component: CustomPermissionDetailUserPart,
          /**
           * The framework of the component. Must be passed correctly.
           */
          framework: 'react',
        },
      },
    }),
  ],
})
```

#### Plugin Mode

```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',
  },
})
```

After configuring your custom user component, synchronize the selected user list to `SheetPermissionUserManagerService` via `setSelectUserList()` for later use.

#### Preset Mode

```typescript
import { SheetPermissionUserManagerService, useDependency } from '@univerjs/preset-sheets-core'

const sheetPermissionUserManagerService = useDependency(SheetPermissionUserManagerService)
// For the specific data structure, refer to: https://github.com/dream-num/univer/blob/b4d4cfa063c9e6d5a82d1fc6b05edc206a415252/packages/sheets-ui/src/services/permission/sheet-permission-user-list.service.ts#L57
sheetPermissionUserManagerService.setSelectUserList([])
```

#### Plugin Mode

```typescript
import { SheetPermissionUserManagerService } from '@univerjs/sheets-ui'
import { useDependency } from '@univerjs/ui'

const sheetPermissionUserManagerService = useDependency(SheetPermissionUserManagerService)
// For the specific data structure, refer to: https://github.com/dream-num/univer/blob/b4d4cfa063c9e6d5a82d1fc6b05edc206a415252/packages/sheets-ui/src/services/permission/sheet-permission-user-list.service.ts#L57
sheetPermissionUserManagerService.setSelectUserList([])
```

## Facade API

The Facade API provides a unified entry point for permissions. Below, we will group common methods by workbook, worksheet, and range.

### Workbook Permissions

#### Get Workbook Permission Instance

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()
```

#### Set Workbook Permission Point

For the `WorkbookPermissionPoint` enum values, see the [workbook permission points list](#workbook-point).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Disable the workbook print permission
await workbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Print, false)
```

Predefined modes:

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Set to owner mode
await workbookPermission.setMode('owner')

// Set to editor mode
await workbookPermission.setMode('editor')

// Set to viewer mode
await workbookPermission.setMode('viewer')

// Set to commenter mode
await workbookPermission.setMode('commenter')
```

Shortcut methods:

* `FWorkbookPermission.setReadOnly()`: Sets read-only mode (equivalent to `setMode('viewer')`)
* `FWorkbookPermission.setEditable()`: Sets editable mode (equivalent to `setMode('editor')`)

#### Get Workbook Permission Point Status

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Check whether the workbook can be printed
const canPrint = workbookPermission.getPoint(univerAPI.Enum.WorkbookPermissionPoint.Print)
console.log('Can print:', canPrint)

// Get the status of all workbook permission points
const snapshot = workbookPermission.getSnapshot()
console.log('Workbook permission snapshot:', snapshot)
```

Shortcut methods:

* `FWorkbookPermission.canEdit()`: Returns `true` if the workbook is editable

#### Collaborator Management

> [!NOTE]
> 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](https://docs.univer.ai/server/collaboration/identity-and-authorization.md). 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()
const workbookPermission = fWorkbook.getWorkbookPermission()

const collaborators = await workbookPermission.listCollaborators()
console.log(collaborators)
```

* Add Collaborators

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Add multiple collaborators at once
await 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 collaborator
await workbookPermission.addCollaborator(
  { userID: 'user1', name: 'John Doe', avatar: 'https://...' },
  univerAPI.Enum.UnitRole.Editor,
)
```

* Update collaborator role

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
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()
const workbookPermission = fWorkbook.getWorkbookPermission()

// Remove multiple collaborators
await workbookPermission.removeCollaborators(['user1', 'user2'])

// Remove a single collaborator
await workbookPermission.removeCollaborator('user1')
```

### Worksheet Permissions

#### Get Worksheet Permission Instance

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()
```

#### Worksheet Protection

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Protect the worksheet, allowing only specified users to edit
const permissionId = await worksheetPermission.protect({
  allowedUsers: ['user1', 'user2'],
  name: 'My Worksheet Protection',
})

// Check if the worksheet is protected
const isProtected = worksheetPermission.isProtected()
console.log('Is worksheet protected:', isProtected)

if (isProtected) {
  // Unprotect the worksheet
  await worksheetPermission.unprotect()
}
```

#### Set Worksheet Permission Point

For the `WorksheetPermissionPoint` enum values, see the [worksheet permission points list](#worksheet-point).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// To set permission points, you must first protect the worksheet
await worksheetPermission.protect()

// Disable the worksheet insert-row permission
await worksheetPermission.setPoint(univerAPI.Enum.WorksheetPermissionPoint.InsertRow, false)
```

Using predefined modes:

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// To set permission points, you must first protect the worksheet
await worksheetPermission.protect()

// Set to editable mode
await worksheetPermission.setMode('editable')

// Set to read-only mode
await worksheetPermission.setMode('readOnly')

// Set to filter/sort only mode
await worksheetPermission.setMode('filterOnly')

// Apply a custom configuration
await worksheetPermission.applyConfig({
  mode: 'readOnly',
  points: {
    [univerAPI.Enum.WorksheetPermissionPoint.InsertRow]: true,
    [univerAPI.Enum.WorksheetPermissionPoint.InsertColumn]: true,
  },
})
```

Shortcut methods:

* `FWorksheetPermission.setReadOnly()`: Sets read-only mode (equivalent to `setMode('readOnly')`)
* `FWorksheetPermission.setEditable()`: Sets editable mode (equivalent to `setMode('editable')`)

#### Get Worksheet Permission Point Status

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Check whether the worksheet can insert rows
const canInsertRow = worksheetPermission.getPoint(univerAPI.Enum.WorksheetPermissionPoint.InsertRow)

// Get the status of all worksheet permission points
const snapshot = worksheetPermission.getSnapshot()
```

Using shortcut methods:

* `FWorksheetPermission.canEdit(): boolean`: Check if the worksheet is editable
* `FWorksheetPermission.canEditCell(row: number, col: number): boolean`: Check if a specific cell is editable
* `FWorksheetPermission.canView(): boolean`: Check if the worksheet is viewable
* `FWorksheetPermission.canViewCell(row: number, col: number): boolean`: Check if a specific cell is viewable
* `FWorksheetPermission.debugCellPermission(row: number, col: number): ICellPermissionDebugInfo`: Get permission debug info for a specific cell

### Range Permissions

#### Get Range Permission Instance

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()
```

#### Set Range Protection

* Protect ranges via the worksheet-level API:

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()

// Protect two ranges: A1:B2 is viewable by everyone but not editable,
// while C3:D4 is editable only by specified users and hidden from others
const rules = await worksheetPermission.protectRanges([
  {
    ranges: [fWorksheet.getRange('A1:B2')],
    options: { name: 'Protected Area 1', allowViewByOthers: true },
  },
  {
    ranges: [fWorksheet.getRange('C3:D4')],
    options: { name: 'Protected Area 2', allowViewByOthers: false, allowedUsers: ['user1'] },
  },
])
console.log(rules)

// List all protection rules on the worksheet
const rules = await worksheetPermission.listRangeProtectionRules()
console.log(rules)

// Delete the first rule
await worksheetPermission.unprotectRules([rules[0].id])

// Or delete a rule via `FRangeProtectionRule.remove()`
await ruleList[0].remove()
```

* Protect a range via the range-level API:

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// Protect the range so only specified users can edit it, while others cannot view it
const rule = await rangePermission.protect({
  name: 'My protected range',
  allowViewByOthers: false,
  allowedUsers: ['user1', 'user2'],
})
console.log(rule)

// List all protection rules covering the range
const rules = await rangePermission.listRules()
console.log(rules)

// Delete all protection rules covering the range
await rangePermission.unprotect()

// Or delete a rule via `FRangeProtectionRule.remove()`
await rules[0].remove()
```

#### Set Range Permission Point

For the `RangePermissionPoint` enum values, see the [range protection points list](#range-point).

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const fRange = fWorksheet.getRange('A1:B2')
const rangePermission = fRange.getRangePermission()

// To set permission points, you must first create a range protection rule
if (rangePermission.isProtected()) {
  const rules = await rangePermission.listRules()

  // Disable editing but enable viewing for the first protection rule
  await rules[0].setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)
  await rules[0].setPoint(univerAPI.Enum.RangePermissionPoint.View, true)
} else {
  const rule = await rangePermission.protect({
    name: 'My protected range',
    allowViewByOthers: false,
    allowedUsers: ['user1', 'user2'],
  })

  // Disable editing but enable viewing for the A1:B2 range
  await rule.setPoint(univerAPI.Enum.RangePermissionPoint.Edit, false)
  await rule.setPoint(univerAPI.Enum.RangePermissionPoint.View, true)
}
```

### Range Permission Rule API

`FRangeProtectionRule` provides the following members:

| API                                                                    | Description                                                                                                                                |
| ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `id: string`                                                           | The unique identifier of the protection rule                                                                                               |
| `permissionId: string`                                                 | The permission ID associated with the protection rule                                                                                      |
| `ranges: FRange[]`                                                     | The ranges covered by the protection rule                                                                                                  |
| `options: IRangeProtectionOptions`                                     | The options of the protection rule, including the name of the rule, whether to allow others to view, and the list of users allowed to edit |
| `updateRanges(ranges: FRange[]): Promise<boolean>`                     | Update the ranges covered by the protection rule                                                                                           |
| `remove(): Promise<boolean>`                                           | Remove the protection rule                                                                                                                 |
| `setPoint(point: RangePermissionPoint, value: boolean): Promise<void>` | Set the status of a specific permission point for the protection rule (e.g., edit/view/delete)                                             |
| `getPoint(point: RangePermissionPoint): boolean`                       | Get the status of a specific permission point for the protection rule (e.g., edit/view/delete)                                             |
| `canEdit(): boolean`                                                   | Check if the protection rule allows editing                                                                                                |
| `canView(): boolean`                                                   | Check if the protection rule allows viewing                                                                                                |
| `canDelete(): boolean`                                                 | Check if the protection rule allows deletion                                                                                               |
| `canManageCollaborator(): boolean`                                     | Check if the protection rule allows managing collaborators                                                                                 |
| `getSnapshot(): RangePermissionSnapshot`                               | Get a snapshot of the current permission status of the protection rule, including all permission points                                    |

```typescript
const fWorkbook = univerAPI.getActiveWorkbook()
const fWorksheet = fWorkbook.getActiveSheet()
const worksheetPermission = fWorksheet.getWorksheetPermission()
const rules = await worksheetPermission.listRangeProtectionRules()
const rule = rules?.[0]

// Get the ID of the first protection rule
const ruleId = rule?.id
console.log(ruleId)

// Get the ranges of the first protection rule
const ranges = rule?.ranges
console.log(ranges)

// Update the ranges of the first protection rule to A1:C3
await rule?.updateRanges([fWorksheet.getRange('A1:C3')])

// Remove the first protection rule
await rule?.remove()
```

### Hide the Permission Dialog

```typescript
univerAPI.setPermissionDialogVisible(false)
```

### Migrating from the Old API

### API Method Description / Migration Guide

#### Get Permission Instance

- **Old API:**
  
    
  
  
  `FWorkbook.getPermission()`

- **New API:**
  
    
  
  
  Workbook: 
  
  `FWorkbook.getWorkbookPermission()`
  
  Worksheet: 
  
  `FWorksheet.getWorksheetPermission()`
  
  Range: 
  
  `FRange.getRangePermission()`

#### Set Workbook Permission Point

- **Old API:**
  
    
  
  
  `FPermission.setWorkbookPermissionPoint(unitId: string, FPointClass: WorkbookPermissionPointConstructor, value: boolean)`

- **New API:**
  
    
  
  
  `FWorkbookPermission.setPoint(point: WorkbookPermissionPoint, value: boolean)`

#### Get Workbook Permission Point Status

- **Old API:**
  
    
  
  
  `FPermission.checkWorkbookPermissionPoint(unitId: string, FPointClass: WorkbookPermissionPointConstructor): boolean`

- **New API:**
  
    
  
  
  `FWorkbookPermission.getPoint(point: WorkbookPermissionPoint): boolean`

#### Set Workbook Edit Permission

- **Old API:**
  
    
  
  
  `FPermission.setWorkbookEditPermission(unitId: string, value: boolean)`

- **New API:**
  
    
  
  
  `FWorkbookPermission.setPoint(univerAPI.Enum.WorkbookPermissionPoint.Edit, value: boolean)`

#### Add Worksheet Protection

- **Old API:**
  
    
  
  
  `FPermission.addWorksheetBasePermission(unitId: string, subUnitId: string)`

- **New API:**
  
    
  
  
  `FWorksheetPermission.protect(options?: IWorksheetProtectionOptions)`

#### Remove Worksheet Protection

- **Old API:**
  
    
  
  
  `FPermission.removeWorksheetPermission(unitId: string, subUnitId: string)`

- **New API:**
  
    
  
  
  `FWorksheetPermission.unprotect()`

#### Set Worksheet Permission Point

- **Old API:**
  
    
  
  
  `FPermission.setWorksheetPermissionPoint(unitId: string, subUnitId: string, FPointClass: WorkSheetPermissionPointConstructor, value: boolean)`

- **New API:**
  
    
  
  
  `FWorksheetPermission.setPoint(point: WorksheetPermissionPoint, value: boolean)`

#### Get Worksheet Permission Point Status

- **Old API:**
  
    
  
  
  `FPermission.checkWorksheetPermissionPoint(unitId: string, subUnitId: string, FPointClass: WorkSheetPermissionPointConstructor): boolean`

- **New API:**
  
    
  
  
  `FWorksheetPermission.getPoint(point: WorksheetPermissionPoint): boolean`

#### Get Permission Info of Specific Cell

- **Old API:**
  
    
  
  
  `FPermission.getPermissionInfoWithCell(unitId: string, subUnitId: string, row: number, column: number)`

- **New API:**
  
    
  
  
  `FWorksheetPermission.debugCellPermission(row: number, col: number): ICellPermissionDebugInfo`

#### Set Range Protection Permission

- **Old API:**
  
    
  
  
  `FPermission.addRangeBaseProtection(unitId: string, subUnitId: string, ranges: FRange[])`

- **New API:**
  
    
  
  
  Worksheet: 
  
  `FWorksheetPermission.protectRanges(configs)`
  
  Range: 
  
  `FRangePermission.protect(options?: IRangeProtectionOptions)`

#### Remove Range Protection Permission

- **Old API:**
  
    
  
  
  `FPermission.removeRangeProtection(unitId: string, subUnitId: string, ruleIds: string[])`

- **New API:**
  
    
  
  
  Worksheet: 
  
  `FWorksheetPermission.unprotectRules(ruleIds: string[])`
  
  Range: 
  
  `FRangePermission.unprotect()`
  
  Range Protection Rule: 
  
  `FRangeProtectionRule.remove()`

#### Set Range Protection Permission Point

- **Old API:**
  
    
  
  
  `FPermission.setRangeProtectionPermissionPoint(unitId: string, subUnitId: string, permissionId: string, FPointClass: RangePermissionPointConstructor, value: boolean)`

- **New API:**
  
    
  
  
  `FRangeProtectionRule.setPoint(point: RangePermissionPoint, value: boolean)`

#### Update Range Protection Permission Ranges

- **Old API:**
  
    
  
  
  `FPermission.setRangeProtectionRanges(unitId: string, subUnitId: string, ruleId: string, ranges: FRange[])`

- **New API:**
  
    
  
  
  `FRangeProtectionRule.updateRanges(ranges: FRange[])`

#### Hide Permission Dialog

- **Old API:**
  
    
  
  
  `FPermission.setPermissionDialogVisible(false)`

- **New API:**
  
    
  
  
  `univerAPI.setPermissionDialogVisible(false)`
