
Challenge my permission-aware RAG: denormalized ACLs in the vector payload
Building a self-hosted enterprise wiki + RAG backend (C++/Drogon, Postgres, Qdrant). Schema is done; about to build retrieval. Want this torn apart before I commit.
The model:
- Postgres is authoritative. Qdrant is rebuildable.
- Ingest: upload -> Redis queue -> chunk -> PG txn (chunks + audit + outbox) -> outbox worker -> embed -> Qdrant upsert.
- Each chunk's Qdrant payload carries the permitted org-unit IDs (inherited from the org hierarchy at ingest time) + sensitivity label + lifecycle state.
- At query: compute the user's effective org scope, hit Qdrant with a MatchAny filter, then re-validate top-K against PG (lifecycle, sensitivity clearance, tenant) before handing to the LLM.
Considered and rejected:
- One Qdrant collection per OU: cardinality explosion.
- PG-only filtering post-search: latency.
- Hashed scope-key: loses set-membership semantics.
What I'm worried about: grant revocation and org-tree edits. Re-encoding every affected chunk via the outbox feels right, but at scale (10k+ docs under a moved subtree) this is a thundering herd. Eventual consistency is fine for me (seconds), but I haven't proven it doesn't rot.
Where does this break that I haven't seen yet?