> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codenullapp.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Component Permissions

> Restrict or hide individual controls inside a custom feature based on the user's role using the Authorization component.

## Overview

Custom features (React code generated or edited through the AI code editor) can wrap any control with the `Authorization` component to apply per-role permissions to it — hide a button for some roles, make a section read-only for others, and leave it fully enabled for the rest. This is UI-level authorization: it controls what a role sees or can interact with inside a feature, it does not replace backend data permissions (see [Authorization](/configurations/authorization)).

## When to use

Use component permissions when you need finer-grained control than hiding or showing the whole feature, for example:

* Hide a "Delete" or "Approve" button for roles that shouldn't perform that action.
* Show a "Finance" section only to roles that should see sensitive data.
* Make a control read-only (`disabled`) for roles that can view but not edit it.

If the entire feature should be restricted, use [feature-level authorization](/configurations/authorization#authorization-by-feature) instead.

## Configuration

### Wrapping a control in code

Import `Authorization` (default export) from `@codenull/common/lib/components/Authorization` and wrap the control, passing a `componentId`:

```jsx theme={null}
import Authorization from '@codenull/common/lib/components/Authorization';

<Authorization componentId="btnNuevoProducto">
  <Button type="primary" onClick={openCreate}>New product</Button>
</Authorization>
```

| Prop          | Type                                 | Description                                                                                                                                                                                                |
| ------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `componentId` | `string`                             | Unique identifier for the wrapped control within the feature. Must be stable and descriptive — if you rename it later in the code, the saved permissions for the old id become orphaned and stop applying. |
| `children`    | `ReactNode \| (result) => ReactNode` | The control(s) to protect, or a render function if you need custom handling (see below).                                                                                                                   |

<Tip>
  The AI agent that generates custom features knows about `Authorization` and wraps controls with it automatically when you ask for role-based permissions on a specific control, instead of writing manual role checks.
</Tip>

### Behavior

* **No configuration saved for a `componentId`** — fail-open: the control renders normally for every role.
* Once at least one role is configured for a `componentId`:
  * Role set to **Enabled** — control renders normally.
  * Role set to **Read only** — the control receives a `disabled` prop.
  * Role not listed in the configuration — the control is not rendered (hidden).
* The **Admin** role always sees the control enabled, regardless of configuration.

### Configuring permissions in the UI

While editing a custom feature (edit mode), every control wrapped in `Authorization` shows a small floating settings button on top of it. Click it to open the permissions modal, which lists every role in the application with three states:

* **Hidden** (default) — the role does not see the control.
* **Enabled**
* **Read only**

The Admin row is locked to **Enabled** and cannot be changed.

<Warning>Screenshot pending update</Warning>

<Note>
  Only Admin users or roles with Feature Designer access can save this configuration. The permissions button also does not appear while the feature is still being created — save the feature first, then reopen it in edit mode to configure component permissions.
</Note>

### Using the hook directly

For custom rendering logic, use `useAuthorization` instead of (or together with) the `Authorization` wrapper:

```jsx theme={null}
import { useAuthorization } from '@codenull/common/lib/components/Authorization';

const { hidden, disabled, loading } = useAuthorization('financeSection');

if (hidden) return null;
```

`Authorization` also accepts a children-as-function to access the same result inline:

```jsx theme={null}
<Authorization componentId="financeSection">
  {({ hidden, disabled }) => (hidden ? null : <Section disabled={disabled} />)}
</Authorization>
```

## Migrating between environments

Component permissions are stored per feature, alongside the existing role permissions. When comparing environments, a feature with component permission differences shows up in the diff labeled with the feature's alias followed by **(component permissions)**, so you can identify and migrate it like any other change. See [Migrate changes between environments](/environments/migrate-changes-between-environments).
