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

# User Management (RBAC)

When the service runs with `CYBORGDB_SERVICE_ROOT_KEY` set, the Python SDK exposes per-index user provisioning on `EncryptedIndex`. These calls require the client to be using the root API key.

<Note>See [Multi-Tenancy & RBAC](../../guides/advanced/multi-tenancy) for the operator-side playbook (modes, key kinds, KMS-backed constraint).</Note>

## create\_user

Mint a per-user API key scoped to this index.

```python theme={null}
EncryptedIndex.create_user(permissions: List[str]) -> Dict[str, str]
```

### Parameters

| Parameter     | Type        | Description                                                                         |
| ------------- | ----------- | ----------------------------------------------------------------------------------- |
| `permissions` | `List[str]` | Non-empty subset of `["read", "write"]`. Enforced cryptographically by the service. |

### Returns

`Dict[str, str]` with two keys:

| Key       | Type  | Description                                                                                 |
| --------- | ----- | ------------------------------------------------------------------------------------------- |
| `user_id` | `str` | Hex-encoded identifier for the new user.                                                    |
| `api_key` | `str` | The user's API key (`cdbk_…`). **Returned exactly once and never stored** — capture it now. |

<Warning>The `api_key` is shown only in this response and is never persisted by the service. Hand it to the user securely. If lost, revoke and re-mint.</Warning>

### Example

```python theme={null}
from cyborgdb import Client

admin = Client(base_url='http://localhost:8000', api_key=ROOT_KEY)
index = admin.load_index('documents')  # KMS-backed: no index_key

user = index.create_user(permissions=['read', 'write'])
user_id = user['user_id']
api_key = user['api_key']
# Hand `api_key` to the new user via a secure channel — it is never recoverable.
# Avoid logging or printing it.
```

### Exceptions

* `ValueError`: invalid permissions, missing root key, RBAC not enabled, or service-side failure.

***

## list\_users

List the users provisioned for this index.

```python theme={null}
EncryptedIndex.list_users() -> List[Dict[str, Any]]
```

### Returns

A list of dicts, each with:

| Key           | Type        | Description                                                                        |
| ------------- | ----------- | ---------------------------------------------------------------------------------- |
| `user_id`     | `str`       | Hex-encoded identifier.                                                            |
| `permissions` | `List[str]` | Subset of `["read", "write"]`. Derived from which wrapped DEKs exist for the user. |

### Example

```python theme={null}
for u in index.list_users():
    print(u['user_id'], u['permissions'])
```

### Exceptions

* `ValueError`: missing root key, RBAC not enabled, or service-side failure.

***

## delete\_user

Revoke a user. Erases their wrapped DEK(s) for this index — even a captured `cdbk_…` token becomes useless on the next request. No propagation lag.

```python theme={null}
EncryptedIndex.delete_user(user_id: str) -> None
```

### Parameters

| Parameter | Type  | Description                                         |
| --------- | ----- | --------------------------------------------------- |
| `user_id` | `str` | Hex `user_id` from `create_user` (or `list_users`). |

### Example

```python theme={null}
index.delete_user('a1b2c3d4e5f6')
```

### Exceptions

* `ValueError`: invalid `user_id`, missing root key, RBAC not enabled, or service-side failure.
