Skip to main content
CyborgDB encrypts every index under a 256-bit AES key (the index key, also called the KEK in the service code). Without that key it is impossible to read the index — you cannot query, list, upsert, or even safely delete its contents. v0.17 supports two completely different ways to provision and hold that key. Pick one per index:
ModeWhat you set on create_indexWho holds the plaintext keyBest for
SDK-suppliedindex_key (32 bytes)Your SDK / applicationDevelopment, evaluation, single-tenant deployments where you already have a secure key store
KMS-backedkms_name (registry slot)The service’s KMS (AWS KMS or Secrets Manager)Production, multi-tenant, BYOK
This page covers the SDK-supplied path. For production, prefer the KMS-backed path — see Per-Index KMS & BYOK for the end-to-end setup.
Do not commit, log, or check in index_key material, and do not store it in plaintext on shared filesystems. Lost keys cannot be recovered — every index wrapped under a lost key becomes permanently unreadable.

Generating a key for development

For local development and evaluation, generate a 256-bit key locally and pass it as index_key (or the SDK’s typed equivalent).
# 32 random bytes, hex-encoded (64 hex chars)
openssl rand -hex 32

Using the key

The same index_key you passed to create_index must be re-supplied on every subsequent request for that index — load_index, upsert, query, get, delete, delete_index. The service stores only a hash to verify the key on each request; it never persists the plaintext.
# Create
index = client.create_index('my_index', index_key=index_key, dimension=384)

# Subsequent calls — same key
index = client.load_index('my_index', index_key=index_key)
index.upsert([{'id': 'a', 'vector': [0.1] * 384}])
results = index.query(query_vectors=[0.1] * 384, top_k=5)

Persisting the key

The service never persists the plaintext key, so your application owns key storage. For development, the Python SDK’s generate_key(save=True) will cache the generated key in ~/.cyborgdb/index_key — useful for evaluation, not for production. For production:
  • Store the key in your platform’s secret store (Vault, AWS Secrets Manager, GCP Secret Manager, Azure Key Vault, k8s Secret) and fetch it at runtime.
  • Or switch to the KMS-backed path so the SDK never holds a long-term key: see Per-Index KMS & BYOK.

Migrating from SDK-supplied to KMS-backed

You cannot rotate an index in place from provider: none to a real KMS provider — the wrapping model changes. The migration path is:
  1. Create a new index with kms_name set instead of index_key.
  2. Replay your data (upsert) into the new index.
  3. Delete the old index.
This is intentional: the persisted envelope for provider: none records no wrap key, so there is nothing for the KMS path to unwrap. Bulk re-encryption against a fresh DEK happens on the upsert.

See also