Complete guide to using langchain-spicedb for adding fine-grained authorization to your LangChain applications.
- What is langchain-spicedb?
- Quick Start - Get running in 5 minutes
- Examples Overview
- Troubleshooting
- Advanced Configuration
langchain-spicedb integrates SpiceDB authorization into LangChain, enabling you to build RAG applications and AI agents that respect fine-grained permissions.
💡 New to langchain-spicedb? See the main README for a quick overview and installation guide, or check the configuration documentation for detailed setup options.
Key Features:
- ✓ Authorization-aware document retrieval for RAG
- ✓ Permission checking tools for AI agents
- ✓ Works with any vector store (Pinecone, Chroma, FAISS, etc.)
- ✓ Efficient bulk permission checks using SpiceDB's native API
- ✓ Async/sync support
- ✓ Production-ready with TLS and fail-open modes
Why use it?
In multi-tenant applications, healthcare systems, or any environment with sensitive data, you need to ensure users only access documents they're authorized to see. langchain-spicedb makes this transparent:
# Without authorization - everyone sees everything
retriever = vector_store.as_retriever()
docs = retriever.invoke("query") # Returns all matches
# With authorization - automatic filtering
retriever = SpiceDBRetriever(
base_retriever=vector_store.as_retriever(),
subject_id=user_id,
resource_type="article",
permission="view",
...
)
docs = retriever.invoke("query") # Returns only authorized documentsGet up and running in 5 minutes:
docker run --rm -p 50051:50051 \
authzed/spicedb serve \
--grpc-preshared-key "somerandomkeyhere" \
--grpc-no-tlsKeep this running in a terminal window.
# macOS
brew install authzed/tap/zed
# Linux
curl -L https://github.com/authzed/zed/releases/latest/download/zed-linux-amd64 -o zed
chmod +x zed
sudo mv zed /usr/local/bin/Configure zed:
zed context set local localhost:50051 somerandomkeyhere --insecureCreate a file schema.zed:
definition user {}
definition article {
relation viewer: user
relation editor: user
permission view = viewer + editor
permission edit = editor
}
This schema defines:
- user: Represents people in your system
- article: Represents documents/content
- viewer relation: User can see the article
- editor relation: User can modify the article
- view permission: Granted to viewers and editors
- edit permission: Granted to editors only
Apply it:
zed schema write schema.zed# Tim can view articles 123 and 456
zed relationship create article:123 viewer user:tim
zed relationship create article:456 viewer user:tim
# Alice can view article 789 and edit article 123
zed relationship create article:789 viewer user:alice
zed relationship create article:123 editor user:aliceWhat this means:
- Tim has view permission on articles 123 and 456
- Alice has view permission on article 789
- Alice has edit permission on article 123 (which also grants view)
Create a .env file in the examples directory (copy from .env.example):
cp .env.example .envThen edit .env with your values:
# SpiceDB Configuration
SPICEDB_ENDPOINT=localhost:50051
SPICEDB_TOKEN=somerandomkeyhere
# User to test as
SUBJECT_ID=tim
# OpenAI API Key (optional, for full RAG demos)
OPENAI_API_KEY=sk-your-key-herepip install -e ".[all]"# No OpenAI API key needed for basic demos
python examples/retriever_example.py
python examples/tool_example.py
# With OpenAI for full RAG demo (optional)
export OPENAI_API_KEY=sk-...
python examples/retriever_example.pyexamples/
├── README.md # This file
├── retriever_example.py # SpiceDBRetriever demo
├── tool_example.py # SpiceDBPermissionTool demo
├── langchain_example.py # Custom chains with SpiceDBAuthLambda
└── langgraph_visualization_example.py # LangGraph integration
What it does: Automatically filters retrieved documents based on user permissions before passing them to an LLM.
Use cases:
- Multi-tenant SaaS (users only see their organization's data)
- Healthcare (doctors only access assigned patient records)
- E-commerce (different docs for free/premium customers)
Key features:
- Wraps any LangChain retriever
- Transparent authorization filtering
- Works with vector stores (Pinecone, Chroma, FAISS)
- Single bulk API call for all permission checks
- Runs without OpenAI for demos
Run it:
# Basic demo (no API key needed)
python examples/retriever_example.py
# Full RAG demo
export OPENAI_API_KEY=sk-...
python examples/retriever_example.py
# Test different users
export SUBJECT_ID=alice
python examples/retriever_example.pyExpected output:
Documents from base retriever (before authorization): 4
- Python Basics (ID: 123)
- JavaScript Guide (ID: 456)
- ML Introduction (ID: 789)
- SpiceDB Overview (ID: 101)
Documents after SpiceDB authorization filter (user: tim): 2
✓ Python Basics (ID: 123)
✓ JavaScript Guide (ID: 456)
SpiceDB filtered out 2 unauthorized documents
What it does: Gives AI agents the ability to check permissions before taking actions.
Use cases:
- Content management (agent checks edit permissions)
- Admin panels (agent verifies admin rights)
- Document workflows (agent checks approval permissions)
Key features:
- Single permission checks
- Bulk permission checks (multiple resources at once)
- Works with LangChain agents
- Direct usage without agents
- Runs without OpenAI for basic demos
Run it:
# Basic demo (no API key needed)
python examples/tool_example.py
# With agent (requires OpenAI)
export OPENAI_API_KEY=sk-...
python examples/tool_example.pyExpected output:
Agent Response:
User tim CAN view article 123. They have the necessary 'view' permission.
Bulk check result:
User tim can access: 123, 456
User tim cannot access: 789
What it does: Demonstrates how to add authorization as a node in LangGraph workflows with state management and observability.
Use cases:
- Complex multi-step agentic workflows
- Workflows requiring authorization metrics and observability
- State-based applications where you need to track authorization decisions
- Production LangGraph applications with permission-aware flows
Key features:
- Authorization as a graph node using
create_auth_node() - Authorization metrics available in state (
auth_results) - Works with
RAGAuthStatefor typed state management - Shows how to integrate authorization into LangGraph's state machine
Run it:
# Works without OpenAI - shows graph structure and flow
python examples/langgraph_visualization_example.py
# Test different users
export SUBJECT_ID=tim
python examples/langgraph_visualization_example.pyExpected output:
METHOD 1: Inspect Graph Nodes
Nodes: ['retrieve', 'authorize', 'generate']
✅ Authorization node EXISTS in the graph
METHOD 2: Inspect Graph Edges (Execution Flow)
Execution flow:
__start__ → retrieve
retrieve → authorize
authorize → generate
generate → __end__
METHOD 6: Authorization Metrics
Total retrieved: 3
Total authorized: 2
Authorization rate: 66.7%
Check latency: 12.34ms
What it demonstrates:
- Graph structure inspection and visualization
- Live execution tracing with state updates
- Authorization metrics for monitoring and debugging
- Mermaid diagram generation for documentation
Read this doc for more comprehensive examples on using SpiceDB in LangGraph.
Low-level authorization filtering using SpiceDBAuthLambda with LangChain Expression Language (LCEL).
Note: For most use cases, prefer SpiceDBRetriever (example 1)
Having issues? The Configuration Guide has comprehensive troubleshooting steps for:
- SpiceDB Connection Errors - Connectivity and authentication issues
- No Documents Returned - Permission and relationship problems
- Schema Errors - Type and permission mismatches
- Invalid Resource IDs - ID format validation
- AsyncIO Errors - Async/sync usage patterns
- Port Conflicts - Docker port management
- Missing Metadata - Document metadata requirements
Quick diagnostic:
# Verify SpiceDB is running
docker ps | grep spicedb
# Test connection
zed permission check article:123 view user:tim
# Check environment
echo $SPICEDB_ENDPOINT
echo $SPICEDB_TOKENFor detailed solutions, see the Troubleshooting section in the configuration guide.
For production deployments and advanced use cases, see the Configuration Guide which covers:
- TLS/SSL Configuration - Secure production deployments
- Fail-Open vs Fail-Closed - Availability vs security trade-offs
- Bulk Permission Checks - Performance optimization (automatic)
- Custom Subject Types - Service accounts, organizations, etc.
- Environment Variables - Configuration management
- Logging and Debugging - Troubleshooting tools
- Production Best Practices - Complete production setup
Quick production setup:
retriever = SpiceDBRetriever(
base_retriever=vector_store.as_retriever(),
spicedb_endpoint=os.getenv("SPICEDB_ENDPOINT"),
spicedb_token=os.getenv("SPICEDB_TOKEN"),
subject_id=os.getenv("USER_ID"),
resource_type="article",
resource_id_key="article_id",
permission="view",
use_tls=True, # Enable for production
fail_open=False, # Fail closed (secure)
)See the complete configuration reference for all options and detailed examples.
- LangChain Documentation: https://python.langchain.com/
- SpiceDB Documentation: https://authzed.com/docs
- SpiceDB Playground: https://play.authzed.com (interactive schema design)
- langchain-spicedb GitHub: https://github.com/authzed/langchain-spicedb
- SpiceDB Discord: https://discord.gg/spicedb
- LangChain Discord: https://discord.gg/langchain
- ✅ Complete Quick Start
- Run examples with your data
- Design your SpiceDB schema for your use case
- Integrate into your application
- Deploy with SpiceDB Cloud for production
- Open an issue: https://github.com/authzed/langchain-spicedb/issues
- Check SpiceDB docs: https://authzed.com/docs
- Join Discord communities (links above)
Happy building with langchain-spicedb! 🚀