Claude
Skills
Sign in
Back

nocobase-acl-manage

Included with Lifetime
$97 forever

Task-driven ACL governance through nb CLI for role lifecycle, global role mode, permission policy, user-role membership, and risk assessment. Use when users describe business permission outcomes instead of raw command arguments.

Productivity

What this skill does


# Goal

Turn ACL and permission governance into a task-driven workflow so users can ask for business outcomes while the skill handles:

- CLI command selection and argument shaping
- capability checks and safety guards
- write confirmation and readback evidence
- risk-oriented explanation for high-impact changes

# Scope

- This skill is CLI-first for reads and writes.
- Tasks are grouped into five domains:
- role
- global role mode
- permission
- user
- risk assessment
- Every write task follows `plan -> confirm -> apply -> readback`.
- `global role mode` is treated as a global system policy, not a per-role field.

# Non-Goals

- Do not bypass CLI by calling direct REST endpoints.
- Do not mutate ACL through ad-hoc database operations.
- Do not create temporary script files to execute ACL writes.
- Do not invoke other skills for env/plugin bootstrap; use direct `nb` commands in this skill.
- Do not hide high-impact blast radius (global mode, broad snippets, broad strategy actions).
- Do not claim one-click coverage for workflows that require governance review.

# Canonical Task Model

## A) Role Domain

| Task | User Outcome | Required Inputs | Optional Inputs |
|---|---|---|---|
| `role.audit-all` | list all roles with comparable policy summary | none | `data_source_key`, `output` |
| `role.create-blank` | create a role with default read-only baseline (single creation mode) | `role_name` | `role_title`, `description`, `hidden`, `allow_configure`, `allow_new_menu` |
| `role.compare` | explain differences between roles | `role_names[]` | `data_source_key`, `output` |

## B) Global Role-Mode Domain

| Task | User Outcome | Required Inputs | Optional Inputs |
|---|---|---|---|
| `global.role-mode.get` | read current global role mode | none | `output` |
| `global.role-mode.set` | switch global role mode | `role_mode` | `strict_mode` |

`role_mode` enum mapping:

- `default`: independent role usage (no union mode)
- `allow-use-union`: union mode available, role switching still allowed
- `only-use-union`: force union mode for multi-role users

## C) Permission Domain

| Task | User Outcome | Required Inputs | Optional Inputs |
|---|---|---|---|
| `permission.system-snippets.set` | set role-level system snippets | `role_name`, (`snippet_preset` or `snippets`) | none |
| `permission.route.desktop.set` | set desktop route permissions for a role | `role_name`, `route_ids[]` | `set_mode` (`set` or `add` or `remove`) |
| `permission.data-source.global.set` | set global strategy actions for all tables in one data source | `role_name`, `global_actions[]` | `data_source_key` |
| `permission.data-source.resource.set` | set independent actions for one or more collections | `role_name`, (`collection_hint` or `collection_hints[]`), `actions[]` | `data_source_key`, `fields_map`, `scope_map`, `resource_scope` (`all` by default) |
| `permission.scope.manage` | create/update/list reusable scopes | `scope_task` | `data_source_key`, `scope_id`, `scope_payload` |

## D) User Domain

| Task | User Outcome | Required Inputs | Optional Inputs |
|---|---|---|---|
| `user.assign-role` | assign one role to one or many users | `role_name`, (`user_ids[]` or `user_filter`) | `allow_generic_association_write` |
| `user.unassign-role` | remove one role from one or many users | `role_name`, (`user_ids[]` or `user_filter`) | `allow_generic_association_write` |
| `user.audit-role-membership` | inspect users bound to roles | (`role_name` or `user_id`) | `output` |

## E) Risk Domain

| Task | User Outcome | Required Inputs | Optional Inputs |
|---|---|---|---|
| `risk.assess-role` | risk score and rationale for one role | `role_name` | `data_source_key`, `output` |
| `risk.assess-user` | risk score based on user-role-permission relationship | `user_id` | `data_source_key`, `output` |
| `risk.assess-system` | system-level ACL governance risk summary | none | `data_source_key`, `output` |

Role creation interaction policy:

- always create with the same default read-only baseline (`role.create-blank`)
- `role_name` must use NocoBase role uid format with `r_` prefix
- if user input has no `r_` prefix, normalize to `r_<normalized_name>` and show normalized value in confirmation/readback
- do not ask users to choose role archetypes (for example, "employee/auditor/manager/custom")
- if `role_name` is provided, execute creation directly
- after creation succeeds, move to permission assignment guidance
- permission follow-up options: system snippets, desktop routes, data-source global strategy, data-source resource strategy

Resource permission interaction policy:

- before executing `permission.data-source.resource.set`, always confirm:
- data source key (`main` by default unless user specifies another)
- resolved target collection(s)
- action list
- data scope (`all` by default when user does not specify)
- disambiguate operation verbs from ACL action names:
- phrases like `add table permission` / `configure permission` describe the operation, not ACL action `create`
- only treat `create` as selected action when user clearly asks for data-creation capability (`can create records` / `can add data`)
- user does not need to provide exact technical collection names
- accept business names or keywords as `collection_hint(s)`
- resolve real collection names from the selected data source collection list
- if matching is ambiguous, present candidates and ask user to choose
- if no match is found, ask user for a clearer business keyword
- resolve scope binding before write:
- if user does not specify scope, default to `all`
- `all` -> built-in scope `key=all` id in target data source
- `own` -> built-in scope `key=own` id in target data source
- `custom` -> user-specified scope id (or resolved scope key)
- do not leave action scope as `null` when final scope is `all` or `own`
- write completeness (hard rule):
- for `permission.data-source.resource.set`, execute one complete write payload per target collection
- the write payload must include `usingActionsConfig: true`
- the same payload must include the final `actions[]` set, with explicit scope binding (`scopeId` or `scopeKey`) for `all|own` and explicit non-empty `fields` arrays for field-configurable actions
- do not stage writes as "set actions first, then patch fields/scope/usingActionsConfig"
- before any write, show confirmation summary (data source + resolved collections + actions + scope)
- when scope is defaulted, confirmation must explicitly state `scope=all (default)` and allow user override
- if any required item is missing or unresolved, ask user first and do not write
- default field rule: all fields
- full-field default must be written as explicit field-name lists resolved from target collection metadata
- do not use `fields=[]` as a full-field default marker
- if user did not provide field-level restrictions, apply full-field permission for each selected action
- apply full-field default to every selected action that supports field configuration (`create`, `view`, `update`, `export`, `importXlsx`)
- full-field default must include system fields returned by metadata (for example `sort`, `createdBy`, `createdById`, `updatedBy`, `updatedById`) unless user explicitly asks to exclude them
- use technical field names (`field.name`) for writes, never display titles
- do not auto-drop fields only because they are system/context/relation/hidden; only exclude when user intent explicitly restricts them
- `view` action must default to all fields for that collection
- if user explicitly asks for `all permissions` on a collection, resolve runtime available actions and confirm expanded action set before write

# Input Contract

| Input | Required | Default | Validation | Clarification Question |
|---|---|---|---|---|
| `task` | yes | none | one of canonical tasks or alias | "Which ACL governance task should run?" |
| `role_name` | conditional | none | role exists for update/audit tasks; write tasks normalize to `r_*` uid | "Which role should be targ
Files: 17
Size: 122.1 KB
Complexity: 66/100
Category: Productivity

Related in Productivity