RAG Authorization: Interactive Demo | AuthZed
Authorization for RAG
See how retrieval-augmented generation can leak confidential data, then how SpiceDB prevents it.
A walkthrough of an insecure chatbot, the failure mode, and the SpiceDB integration that prevents it. Try both sides live.
RAG Without Authorization
Try it yourself. Ask a question that accesses a document you're not allowed to see. The AI returns the confidential data anyway.
Acme Corp AI · Authorization OFF
User Bob (Eng)
Question Q4 salaries
Ask AI
Try it
Ask Bob (Eng) the Q4 salary question, or Alice (HR) about Project X. Same question, wrong user. The AI should refuse, but without authorization it returns the document anyway.
Why RAG Leaks Data
Standard RAG pipelines retrieve documents based on semantic similarity, not on who's allowed to see them.
Without Authorization
- User Query
- semantic search
- Vector DB
- retrieve top-K docs
- no authz check
- LLM
- full context
- includes restricted docs
- Data Leak
- confidential exposed
- user sees what they shouldn’t
Vector DB has no ACLs. Embeddings are stored flat. A semantic search returns all similar documents regardless of who ingested them.
LLM uses all context. The model synthesizes everything in its context window. It has no concept of data sensitivity or access rights.
Output leaks secrets. Salary data, confidential specs, private HR records. The LLM will summarize anything it can access, regardless of sensitivity.
RAG with Authorization Infrastructure
Now try the same question with authorization enabled. The vector DB retrieves first, then SpiceDB checks permissions on every returned document ID before anything reaches the LLM.
Acme Corp AI · Authorization ON
User Bob (Eng)
Question Q4 salaries
Ask AI
Post-Filter Authorization
Retrieve first, check permissions second
- User Query
- semantic search
- Vector DB
- retrieve top-K docs
- returns doc IDs + metadata
- SpiceDB
- CheckPermission per doc ID
- post-filter on metadata
- LLM
- authorized docs only
The vector DB retrieves the top-K results first. A CheckPermissionRequest is then performed on every document ID returned, using the article_id stored in document metadata. Only documents the user is authorized to view are passed to the LLM.
How SpiceDB Enforces This
Every permission check is evaluated against a schema and a set of relationships, in milliseconds.
definition user {}
definition document {
relation viewer: user
permission view = viewer
}
The schema defines types and their permission relationships. viewer grants view permission.
Relationships
Streaming
| Resource | Relation | Subject |
|---|---|---|
| document:q4-salaries | viewer | user:alice |
| document:hr-policy | viewer | user:alice |
| document:all-hands | viewer | user:alice |
| document:eng-roadmap | viewer | user:bob |
| document:project-x | viewer | user:bob |
| document:all-hands | viewer | user:bob |
Computed Access Matrix
| Document | Alice (HR) | Bob (Eng) |
|---|---|---|
| Q4 Salary Forecast | ✓ | ✗ |
| Engineering Roadmap | ✗ | ✓ |
| All-Hands Notes | ✓ | ✓ |
| Product Spec: Project X | ✗ | ✓ |
| HR Policy Handbook | ✓ | ✗ |
The Problem Compounds With Agents
When an AI agent acts on behalf of a user, it should only be able to access what that user can access, nothing more.
AI Assistant acting as Bob
→ ↓
Q4 Salary Forecast
document
→ ↓
✗ DENIED
Bob can't view salary data, so his AI assistant can't either.
AI Assistant acting as Alice
→ ↓
Q4 Salary Forecast
document
→ ↓
✓ ALLOWED
Alice is in HR and can view salary data, so her AI assistant can too.
agentic-delegation.zed
An agent can only view what the user it represents can view.
definition user {
relation delegate: agent
}
definition agent {}
definition document {
relation viewer: user
permission view = viewer + viewer->delegate
}
You just saw the pattern.