How do you implement RAG with access control and document permissions?
Secure RAG systems enforce document-level permissions during retrieval, ensuring users only access information they are authorized to see. Architecture: store access control metadata with each document chunk (allowed users, groups, roles), filter retrieval results based on the querying user's permissions before passing to the LLM, and audit all access. Implementation: during ingestion, extract document permissions from the source system (SharePoint permissions, Google Drive sharing, database row-level security), store permissions as metadata on each chunk (allowedusers, allowedgroups arrays), and during retrieval apply permission filters before vector search. Pre-filtering vs post-filtering: pre-filtering (apply metadata filter during vector search) is more efficient and secure, post-filtering (retrieve then remove unauthorized results) wastes compute and may leave too few results. Most vector databases support metadata filtering during search. Group-based access: map users to groups/roles, store group-level permissions on chunks, and implement permission inheritance (team access inherits to team members). Permission synchronization: periodically sync permissions from source systems, implement event-driven updates for immediate permission changes (employee leaves, access revoked), and handle permission propagation delays with a safety buffer. Dynamic permissions: for systems where permissions change frequently, implement real-time permission checks rather than cached permissions. Audit logging: log every retrieval with user identity, query, retrieved chunks, and permission decisions. Testing: verify that users cannot access unauthorized content through any query pattern, test permission revocation latency, and implement automated permission compliance checks.