Lead · Core path · 7 chapters
Permission-aware RAG
Per-user filtering, row-level security, never leaking documents across tenants
A single cross-tenant citation can become a serious breach, so authorization must be enforced before retrieval and continuously tested against stale state and hostile inputs.
Read these first
What you will know
Enforce per-user document access at the retrieval layer
Apply the caller’s effective permissions inside the datastore query or index filter, with a fail-closed path when identity or policy data is unavailable.
Prove that user A cannot retrieve user B's documents
Use separate tenants with uniquely identifiable canary documents and assert zero unauthorized IDs, snippets, or citations across repeated queries.
Explain why filtering after retrieval is both slow and risky
The generator, logs, traces, and caches may already receive unauthorized chunks, while discarding them afterward also wastes retrieval and reranking work.
Handle permission changes without a full reindex
Define and test a revocation SLA so changed grants affect indexed chunks without rewriting embeddings or blocking unrelated authorized reads.
Test the isolation adversarially rather than trusting it
Exercise forged claims, tenant-ID confusion, stale permission caches, concurrent ACL updates, deleted grants, and empty-result behavior in automated tests.
Chapters
- 1
Post-filtering leaks into traces, logs and caches, not the response
Retrieving the top 50 chunks from a shared index and dropping the unauthorized ones before assembling the prompt returns only permitted text to the user, which is why security signs it off. The unauthorized chunks have nonetheless entered your process: retrieval traces, request logs and any query-keyed cache, all with longer retention and broader read access than the response body. A top-50 filtering down to two also leaves the generator nothing to answer from.
- 2
Authorize on verified token claims, never on a gateway header
Pushing the caller's effective grants into the datastore query or index filter is the enforcement point, and it is only as trustworthy as the identity it was built from. A pen-tester who forges the tenant_id header the gateway sets receives another tenant's documents while the filter works exactly as designed, so a stricter filter fixes nothing. Covers resolving grants from verified claims, and what your vector store does with metadata predicates internally.
- 3
A failed permission lookup says nothing about what the caller may read
When the permission service times out under load, returning results from an incomplete grant set is a decision to guess. Fail closed, then price that honestly: a dependency at 99.9% underneath an endpoint contracted at 99.95% is a real conflict, not a principle to recite. The serve-stale proposal that follows has a bound that evaporates during the very incident it exists for, because a TTL can only evict entries that refresh can replace. If a degraded mode is going to exist anyway, these are the bounds worth arguing for: deny any resource whose grant changed inside the stale window, narrow scope to resources the caller owns outright, and cap the mode by wall clock behind an explicit break-glass and audit trail.
- 4
An empty result and an unknown permission set are different answers
Both hand the generator zero passages, and only one of them is safe to answer from, so the retrieval path has to keep them apart once the candidate list comes back empty: permitted-to-see-nothing is a normal result, could-not-determine-what-you-may-see is an error. Then the disclosure question, because "no results found" and "not permitted" are different sentences and picking the wrong one turns the assistant into an oracle for whether a document exists — an inference channel that also runs through response latency and citation counts. Last, a generator handed empty context will answer from parametric memory unless something stops it, which is the behaviour the canary tests later in this topic assert on.
- 5
Copying an ACL onto every chunk makes revocation a rewrite
Stamping each chunk's metadata with its source document's allowed-user list works until an offboarding revokes access to a 40,000-document folder under a five-minute commitment. The work a revocation causes stays proportional to how many chunks the grant touches, so a faster bulk-update job only moves the folder size at which the SLA breaks. Store a group or resource reference on the chunk and resolve effective grants at query time instead.
- 6
A revocation SLA is a number you measure, not a shrug at consistency
A load test races a revocation against a query and one time in fifty the revoked user receives the document 300ms after the commit. Calling that acceptable eventual consistency is defensible only with a figure attached: the maximum interval between a grant change committing and the last request that can still observe the old grant. Write it down, measure it with a revoke-and-query loop, and alert on the observed tail rather than on the job finishing.
- 7
A green isolation test that never held anything worth leaking
A CI assertion that tenant A's queries return no tenant B documents can stay green through an incident: the fixture may hold nothing that would rank for A's queries, the assertion may read only the final answer text, or the fixture may be seeded once and never mutated. Rebuild it around greppable canaries, queries designed to attract them, and assertions over retrieved IDs and traces. Then decide whether per-tenant indexes are the permanent fix.
External resources
- RAG with Permissionssupabase.com
Postgres RLS applied to pgvector similarity search, with working SQL policies.
- RAG with Access Controlpinecone.io
Walks through stamping ACLs into chunk metadata and filtering at query time.
- The Right Approach to Authorization in RAGosohq.com
Compares pre-filter, post-filter and inline auth so you pick the right enforcement point.
- Database Permissions 101: From Fine-Grained Policies to RAG SecurityMongoDB
Shows how row/field-level policies map onto a retrieval layer.
- Fine-Grained Authorization: The Missing Piece in Agentic AI Security - Shivay Lamba - NDC SydneyNDC Conferences
Conference talk on enforcing per-user authz before context reaches the model.