This Learn article was written by Sohan Maheshwar, Lead Developer Advocate at AuthZed.Securing Knowledge Retrieval using SpiceDB and ReBACRetrieval-Augmented Generation (RAG) pipelines are powerful tools for grounding large language models (LLMs) in private or domain-specific knowledge. By fetching relevant documents from a vector database and including them in the model’s prompt, RAG enables more accurate and context-aware answers.However, this capability introduces a serious risk: information leakage. If different users have different levels of access to data, as they do in most real-world systems, your RAG pipeline must enforce those access boundaries. In fact, OWASP lists Sensitive Information Disclosure, Excessive Agency & Vector and Embedding Weaknesses in their list of Top 10 Risks for Large Language Model Applications.That’s where access control comes in. Instead of trusting the RAG system to “just do the right thing,” we can integrate an authorization layer that determines which resources a given identity can access. In this post, we’ll explore how to achieve that using SpiceDB, an open-source, Zanzibar-inspired permission system.We’ll cover how SpiceDB works, how to model permissions, and how to apply access control both before and after retrieval in a RAG pipeline built with Pinecone and OpenAI embeddings.Authentication and Authorization PrimerBefore we get to the implementation, let’s review two foundational concepts: authentication and authorization.Authentication: Verifying who a user is. Usually handled through credentials, OAuth, or an identity provider.Authorization: Deciding what that user can do once authenticated — which resources they can read, write, or modify.Several access control paradigms exist:ACL (Access Control Lists): Simple user-resource mappings.RBAC (Role-Based Access Control): Permissions granted through roles like “admin” or “editor.”ABAC (Attribute-Based Access Control): Decisions based on attributes such as department, geography, or clearance.ReBAC (Relationship-Based Access Control): Permissions determined by relationships between users and resources.For large, dynamic, and context-rich applications (such as RAG pipelines) ReBAC provides the flexibility and scalability we need. It models access as a graph of relationships rather than hard-coded rules.Enter Google ZanzibarGoogle Zanzibar is the internal authorization system that Google built to manage permissions across all their products and services. Think of it as the system that decides whether you can view a shared Google Doc, edit a file in Google Drive, or access a specific Google Cloud resource. Rather than each Google product implementing its own permission system, they all use Zanzibar as a shared service.Zanzibar systems shine when the requirement is for:Low-latencyHigh-throughput authorization checksGlobal consistency of relationship dataComposable and hierarchical permission modelsTurns out, RAG systems typically have these requirements. In addition, embeddings need to retain the permissions from where the data was originally sourced. This means that the permission system needs to be powerful and flexible enough to model all of the source systems' permission systems. These requirements make ReBAC & a Zanzibar-like system the perfect way to implement fine-grained permissions for RAG.SpiceDBWhile Zanzibar is an internal system at Google, there are open source implementations based on the whitepaper that Google released in 2019. Among those, SpiceDB is the most scalable and consistent open-source implementation of Google’s Zanzibar authorization model, used by businesses such as OpenAI, Workday, Turo, Netflix and more.SpiceDB stores access relationships as a graph, where nodes represent entities (users, groups, documents) and edges represent relationships (like “viewer,” “editor,” or “owner”). Fundamentally, authorization logic can be reduced to asking a single question:Is this actor allowed to perform this action on this resource?In SpiceDB parlance, this actor and this resource are both Objects and this action is a Permission or Relation. Here’s a Google Docs style example where a user can be either a reader or a writer of a document. A reader can only read the document, whereas a writer can read and write the document.You can represent this use case using a schema like this:definition user {}