read and/or write access. A user then loads the index with their own per-user key (KEK) and is restricted to the permissions they were granted.
Key model. Each index is encrypted under a 32-byte Key-Encryption-Key (KEK) — the
index_key. The root KEK holder mints per-user keys; the set of wraps that exist defines the permission set — there is no separate permission flag. A read-only user simply has no write wrap. Managing users (create / delete / list) is always gated on the root KEK.create_user_keys
Creates per-user wrapped keys granting the specified permissions on the index. Gated on the root index KEK.Parameters
| Parameter | Type | Description |
|---|---|---|
user_id | bytes | 16-byte unique identifier for the user. |
user_kek | bytes | 32-byte per-user key (KEK). This is the key the user will pass as index_key when loading the index. |
permissions | List[str] | Subset of {"read", "write"}. At least one permission must be granted. |
index_key | bytes | (Keyword-only, required) The 32-byte root index KEK. Acts as the admin gate authorizing user management. |
Exceptions
ValueError
ValueError
- Throws if
permissionsis empty or contains values outside{"read", "write"}. - Throws if
user_idor the keys are the wrong length.
RuntimeError
RuntimeError
- Throws if the supplied
index_keyis not the root KEK. - Throws if the user keys could not be created.
Example Usage
delete_user_keys
Revokes a user’s keys. Idempotent — revoking a non-existent user is a no-op. Gated on the root index KEK.Parameters
| Parameter | Type | Description |
|---|---|---|
user_id | bytes | 16-byte identifier of the user to revoke. |
index_key | bytes | (Keyword-only, required) The 32-byte root index KEK. |
Example Usage
list_user_keys
Lists the users with keys on the index and their effective permissions. Gated on the root index KEK.Parameters
| Parameter | Type | Description |
|---|---|---|
index_key | bytes | (Keyword-only, required) The 32-byte root index KEK. |
Returns
List[dict]: One dictionary per user, each with the keys:
user_id(bytes): the 16-byte user identifierhas_read(bool): whether the user has a read wraphas_write(bool): whether the user has a write wrap
Example Usage
Loading the index as an RBAC user
A user loads the index by passing their ownuser_kek as the index_key and their user_id (keyword-only) to load_index():
query / get / list_ids, but upsert, delete, and train are rejected. Admin operations (create_user_keys, delete_user_keys, list_user_keys, delete_index()) always require the root KEK and reject per-user contexts.