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
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
Example Usage
list_user_keys
Lists the users with keys on the index and their effective permissions. Gated on the root index KEK.Parameters
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.