Skip to main content
CyborgDB supports per-user access control (RBAC) on an encrypted index. The holder of the root index KEK can mint per-user wrapped keys, each granting 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

  • Throws if permissions is empty or contains values outside {"read", "write"}.
  • Throws if user_id or the keys are the wrong length.
  • Throws if the supplied index_key is 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 identifier
  • has_read (bool): whether the user has a read wrap
  • has_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 own user_kek as the index_key and their user_id (keyword-only) to load_index():
The permission gate is enforced per operation: a read-only user can 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.
Per-operation key override: every data op accepts keyword-only index_key= and user_id=. In stateless/service deployments that reload the index per request, pass the user’s user_kek as index_key= and their user_id= on each call instead of relying on the key bound at load time.