CyborgDB Python SDK
The CyborgDB Python SDK is the Python client for CyborgDB — the vector database that stays encrypted even while it's searching. Run similarity search directly on encrypted data with client-side keys; only the result of a query is ever decrypted, never the index. Built for Python, it fits into existing AI and data workflows.
This SDK talks to cyborgdb-service, which you self-host in your own VPC or on-prem and run alongside your app. Install and start it separately. See our docs for more info.
Key Features
- Encryption-in-use: Search runs directly on ciphertext; only the query result is decrypted, never the index or stored vectors
- Encrypted ANN: Disk-backed encrypted DiskIVF index with recall within 2% of a plaintext baseline (read the benchmarks)
- Filters on encrypted metadata: Combine vector similarity with equality and range predicates in a single request
- BYOK / HYOK: Wrap per-index keys with AWS KMS or AWS Secrets Manager, or hold the key client-side — you control the key material
- Per-tenant key isolation: Per-index, per-user keys with cryptographic RBAC; revoke a user and their keys are erased
- Pythonic API: Familiar client/index interface that integrates with existing Python AI workflows
Getting Started
To get started in minutes, check out our Quickstart Guide.
Install the SDK
- Install
cyborgdb-service
# Pull the CyborgDB Service image
docker pull cyborginc/cyborgdb-service
# Or install via pip
pip install cyborgdb-service
- Install
cyborgdbSDK:
# Install the CyborgDB Python SDK
pip install cyborgdb
Index and query vectors
from cyborgdb import Client
client = Client(
"https://localhost:8000", "your-service-root-key"
) # api_key optional; only if the service was started with one
# Generate a 32-byte encryption key
index_key = client.generate_key()
# Create an encrypted index
index = client.create_index(index_name="my-index", index_key=index_key)
# Add encrypted vector items
items = [
{
"id": "doc1",
"vector": [0.1] * 128, # Replace with real embeddings
"contents": "Hello world!",
"metadata": {"category": "greeting", "language": "en"},
},
{
"id": "doc2",
"vector": [0.1] * 128, # Replace with real embeddings
"contents": "Bonjour le monde!",
"metadata": {"category": "greeting", "language": "fr"},
},
]
index.upsert(items)
# Query the encrypted index
query_vector = [0.2] * 128 # 128 dimensions
results = index.query(query_vectors=query_vector, top_k=5)
# Print the results
for result in results:
print(f"ID: {result['id']}, Distance: {result['distance']}")
# ID: doc1, Distance: 1.1314
# ID: doc2, Distance: 1.1314
Run batch queries
# Search with multiple query vectors simultaneously
query_vectors = [[0.1] * 128, [0.2] * 128]
batch_results = index.query(query_vectors=query_vectors, top_k=5)
# Print the results (batch queries return list of lists)
for i, query_results in enumerate(batch_results):
print(f"\nResults for query {i}:")
for result in query_results:
print(f" ID: {result['id']}, Distance: {result['distance']}")
# Results for query 0:
# ID: doc1, Distance: 0.0000
# ID: doc2, Distance: 0.0000
#
# Results for query 1:
# ID: doc1, Distance: 1.1314
# ID: doc2, Distance: 1.1314
Filter results by metadata
# Search with metadata filters
query_vector = [0.1] * 128
results = index.query(
query_vectors=query_vector,
top_k=10,
n_probes=1,
greedy=False,
filters={"category": "greeting", "language": "en"},
include=["distance", "metadata"],
)
# Print the results
for result in results:
print(
f"ID: {result['id']}, Distance: {result['distance']}, Metadata: {result['metadata']}"
)
# ID: doc1, Distance: 0.0000, Metadata: {'category': 'greeting', 'language': 'en'}
Bring Your Own Key (BYOK) via KMS
When the service is configured with a kms.registry entry, the SDK can
delegate key management entirely to the server-side KMS. The service
generates the data encryption key, wraps it under the named KMS slot, and
persists the envelope — the SDK never sees or holds the key.
# Create a KMS-backed index — no index_key from the SDK side.
# 'vendor-kms-slot' must match an entry in the service's cyborgdb.yaml.
index = client.create_index(
index_name="kms-backed-index",
kms_name="vendor-kms-slot",
dimension=128,
metric="euclidean",
)
# Reopening the index later doesn't require a key either; the service
# resolves the data key from the index's stored KMS envelope.
loaded = client.load_index(index_name="kms-backed-index")
loaded.upsert(items)
Alternatively, the SDK can supply the key itself — pass index_key and omit
kms_name. This is the no-KMS path, which the service records internally as
provider: none:
index = client.create_index(
index_name="sdk-keyed-index",
index_key=index_key,
dimension=128,
)
Supply exactly one of index_key / kms_name — passing both is rejected
by the service with a 400, since the named slot already determines the key
source.
Control access with per-user keys
When the service runs with a root admin key (CYBORGDB_SERVICE_ROOT_KEY) set, RBAC
is enabled. The root can mint per-user API keys scoped to a single index,
each with a read / write permission set. Permissions are enforced
cryptographically: a user's wrapped data-encryption keys are their
permission set. A read-only user cannot decrypt for a write operation;
revoking a user erases their keys.
# Admin (root) client: mint users on an existing index.
admin = Client(base_url, api_key=SERVICE_ROOT_KEY)
index = admin.load_index(index_name="kms-backed-index") # KMS-backed (see BYOK)
reader = index.create_user(permissions=["read"])
writer = index.create_user(permissions=["read", "write"])
# Each returns {'user_id': '<hex>', 'api_key': 'cdbk_...'} — the api_key is
# shown ONCE and never stored by the service. Hand it to the user securely.
index.list_users() # [{'user_id': ..., 'permissions': [...]}, ...]
index.delete_user(reader["user_id"]) # revoke; the key stops working immediately
A user authenticates with their cdbk_ key and needs no index key of their own
— they load the index by name and the service resolves its key:
user = Client(base_url, api_key=reader["api_key"])
idx = user.load_index(index_name="kms-backed-index") # no index_key
idx.query(query_vectors=[...], top_k=5) # allowed for 'read'
idx.upsert(items) # raises ValueError for read-only users
User keys resolve the index key server-side, so they work against KMS-backed indexes. SDK-supplied-key indexes (
provider: none) have no server-side key for the service to resolve on a user's behalf. See the service'srbac.mdfor the full design.
Documentation
For more information on CyborgDB, see the Cyborg Docs.
License
The CyborgDB Python SDK is licensed under the MIT License.
Metadata
Release files for cyborgdb 0.18.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cyborgdb-0.18.0.tar.gz | 245.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cyborgdb-0.18.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 388.7 kB
Release files / cyborgdb-0.18.0.tar.gz
| Download URL | cyborgdb-0.18.0.tar.gz |
|---|---|
| Size | 245.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c2339ac36ec3ff428f85a02f741aa520b1c0359790afd983963a6d40a638bf96
|
|
BLAKE2b-256 checksum How to use checksums |
a6a5144d247ff98ce9bb4ae130aa6b47c30465d42a8a903763228e3c7f35a23b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency logRelease files / cyborgdb-0.18.0-py3-none-any.whl
| Download URL | cyborgdb-0.18.0-py3-none-any.whl |
|---|---|
| Size | 143.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f4ca8a4ac55b7eb197ecc40528effa6e59d9fee2b4d82f3610a378841b8d94aa
|
|
BLAKE2b-256 checksum How to use checksums |
8f934f7ea8713420e27800a49c21e721c55ed85190655c7d26d8de169171460d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 1, 2026.
Transparency log