Learn ChromaDB - Privacy & Data Handling
Episode 16 of 23

Learn ChromaDB - Privacy & Data Handling

This episode covers privacy and data handling in ChromaDB: the embedding inversion risk that can reconstruct documents from vectors, data-at-rest encryption, PII handling, retention policies, and data access audit logs for regulatory compliance.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Introduction

Technical security was solidified in episodes 14 and 15. But there is a dimension that is often overlooked: privacy and data handling. A server safe from hackers is not necessarily safe from legal problems. The documents you store in ChromaDB — including those containing personal data — must still be treated according to regulations.

Episode 16 covers four things: the embedding inversion risk, data-at-rest encryption, PII (personally identifiable information) handling, and retention policies along with audit logs. This is material that determines whether your application can pass an audit.

The Embedding Inversion Risk

Can Vectors Recover Text?

Most people treat embeddings as "completely transformed text". A lesser-known fact: embeddings can be partially reversed. Research in embedding inversion shows that from an embedding vector, the original document can be reconstructed — sometimes accurately enough to leak sensitive content.

This is not pure theory: an attacker with access to the collection (or a leaked backup) could try to reconstruct documents from the stored embeddings. An important implication: embeddings are not a substitute for encryption. If the original data is sensitive, treat the embeddings as sensitive too.

PythonMemeriksa apa yang disimpan
data = collection.get(include=["documents", "embeddings"])
print("jumlah item:", len(data["ids"]))
print("dimensi embedding:", len(data["embeddings"][0]))

collection.get(include=["documents", "embeddings"]) shows that the original documents and embeddings are both stored. Even deleting the original documents still leaves embeddings that could potentially be reversed.

Danger

Do not store embeddings of personal data in an unencrypted location. Embedding inversion enables partial document reconstruction — treat embeddings as sensitive as the original text.

Reducing the Inversion Risk

Several strategies reduce exposure:

  • Encrypt storage so embeddings cannot be read without the key.
  • Do not store highly sensitive data (ID card numbers, medical data) in any form without a clear need.
  • Use embedding models tuned with anti-inversion techniques if available.
  • Delete collections containing old data that is no longer needed.

Data-at-Rest Encryption

Disk-Level Encryption

The first layer: encrypt the disk where ChromaDB data lives. This handles the most common scenario — stolen physical media or cloud volumes:

Enkripsi volume cloud
cloud: aktifkan volume encryption (EBS/PD/PV terenkripsi)
lokal: gunakan LUKS atau native disk encryption
backup: enkripsi snapshot di episode 11

In the cloud, enable the provider's built-in volume encryption. In Kubernetes, make sure the StorageClass uses encrypted: true. Backups moved between environments must also be encrypted — plaintext snapshots are a leak point often forgotten.

Application-Level Encryption

For tighter control, encrypt sensitive documents before they enter ChromaDB:

PythonEnkripsi dokumen sebelum simpan
from cryptography.fernet import Fernet
 
kunci = Fernet.generate_key()
fernet = Fernet(kunci)
 
dokumen_terenkripsi = fernet.encrypt(b"isi rahasia").decode()
collection.add(ids=["doc-1"], documents=[dokumen_terenkripsi])

fernet.encrypt(b"isi rahasia") stores the document in encrypted form — readable only by key holders. The trade-off: full-text search and where_document from episode 7 no longer work on encrypted data. For PII cases, this is a fair trade-off.

PII Handling

Avoiding Unnecessary PII

The first rule of PII handling: do not store what you do not need. Before embedding documents, clean the personal data:

PythonRedaksi PII sederhana
import re
 
def redaksi(teks):
    teks = re.sub(r"\b\d{16}\b", "[KARTU]", teks)
    teks = re.sub(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", "[EMAIL]", teks)
    return teks
 
dokumen_aman = redaksi(dokumen_asli)

redaksi(teks) replaces 16-digit card numbers and email addresses with placeholders before the document enters ChromaDB. This habit is far cheaper than cleaning up data after a leak.

Processing Documentation

If your application processes personal data, prepare minimal documentation: what is stored, for what purpose, for how long, and who can access it. This document is not merely a formality — it becomes the basis for answering regulatory and audit questions.

Retention Policies and Audit Logs

Retention Policy: Data Has a Lifetime

A retention policy determines how long data is kept before deletion. A pattern you can apply directly:

PythonHapus data lebih tua dari N hari
import datetime
 
batas = (datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=90)).isoformat()
 
collection.delete(where={"timestamp": {"$lt": batas}})

collection.delete(where={"timestamp": {"$lt": batas}}) deletes all documents with a timestamp older than 90 days. The retention policy — using the $lt filter from episode 7 — runs on a schedule, for example nightly via cron or a Kubernetes job.

Data Access Audit Logs

For compliance, record who accessed what and when. At the application level, wrap query operations with logging:

PythonAudit log sederhana
import logging
 
log = logging.getLogger("chroma-audit")
 
def query_dengan_audit(client, collection_name, query):
    log.info("QUERY collection=%s user=%s", collection_name, get_user())
    hasil = client.get_collection(collection_name).query(query_texts=query)
    log.info("QUERY_DONE collection=%s n=%s", collection_name, len(hasil["ids"][0]))
    return hasil

The query_dengan_audit(...) function logs the request and its results. On large deployments, route audit logs to centralized log aggregation (episode 20) so they are not easily lost.

Closing

Episode 16 closed the privacy side: understanding the embedding inversion risk that can reconstruct documents, encrypting data at rest at both disk and application levels, cleaning PII before it enters ChromaDB, applying scheduled retention policies, and recording data access audit logs for compliance.

Key takeaways:

  • Embeddings can be partially reversed — treat them as securely as the original text.
  • Disk encryption for storage and backups; application encryption for sensitive data.
  • Do not store unnecessary PII; redact before embedding.
  • Retention policies use where={"timestamp": {"$lt": ...}}.
  • Audit logs record who accessed what and when.
  • Compliance is built from documentation and habits, not a single feature.

In the next episode, episode 17, we will discuss scaling and performance — serving millions of vectors with the Rust server, batch operations, index tuning, ef search optimization, metadata pre-filtering, and proper CPU and RAM resource sizing. Your application is growing; it is time to prepare the machines.

Learn ChromaDB - Privacy & Data Handling | Learn ChromaDB