Skip to main content

SpiceDB authorization for LangChain RAG pipelines and agents - fine-grained access control for AI applications

Project description

LangChain-SpiceDB Integration

Authorization library for RAG (Retrieval-Augmented Generation) pipelines using SpiceDB. Designed for LangChain and LangGraph integrations with support for any vector store (Pinecone, FAISS, Weaviate, Chroma, etc.).

This package follows LangChain's official integration guidelines and provides standard LangChain components (BaseRetriever, BaseTool) plus additional middleware patterns.

Features

  • LangChain & LangGraph Integration: First-class support for modern LLM frameworks
  • Vector Store Agnostic: Compatible with Pinecone, FAISS, Weaviate, Chroma, and more
  • Post-Filter Authorization: Filters retrieved documents based on SpiceDB permissions
  • Efficient Bulk Permissions: Uses SpiceDB's native bulk API for optimal performance
  • Observable: Returns detailed metrics about authorization decisions
  • Type-Safe: Full type hints for better IDE support
  • Async by Default: Built for high-performance async operations

Why This Package?

Most RAG pipelines retrieve documents without considering user permissions. This package solves that by:

  1. Post-retrieval filtering: Retrieve best semantic matches first, then filter by permissions
  2. Deterministic authorization: Every document is checked against SpiceDB before being used
  3. Framework integration: Native LangChain and LangGraph components for seamless integration
  4. Vector store agnostic: Not tied to any specific vector database

Which Component Should I Use?

Choose the right component based on your use case:

Component Use Case Best For
SpiceDBRetriever Simple RAG pipelines Drop-in replacement for any retriever. Wraps your existing retriever with authorization.
SpiceDBAuthFilter LangChain chains with middleware Filtering documents in the middle of a chain. Reusable across different users via config.
create_auth_node LangGraph workflows Complex multi-step workflows with state management. Provides authorization metrics in state.
SpiceDBPermissionTool Agentic workflows Give agents the ability to check permissions before taking actions.
SpiceDBBulkPermissionTool Agentic workflows (batch) Same as above but for checking multiple resources at once.

Quick Decision Guide

Use SpiceDBRetriever if:

  • You have a simple RAG pipeline
  • You always use the same user per retriever instance and you don't need to reuse the retriever across different users

Use SpiceDBAuthFilter if:

  • You're building LangChain LCEL chains
  • You want to reuse the same chain for multiple users
  • You need to pass user context at runtime via config

Use create_auth_node if:

  • You're using LangGraph for complex workflows
  • You need state management and observability
  • You're building multi-step agentic workflows

Use SpiceDBPermissionTool / SpiceDBBulkPermissionTool if:

  • You're building agents with LangChain
  • Your agent needs to check permissions as part of its decision-making and you want agents to explain why actions are allowed or denied
  • You're implementing permission-aware automation

Example: Same Pipeline, Different Patterns

Pattern 1: SpiceDBRetriever (simplest)

retriever = SpiceDBRetriever(
    base_retriever=vectorstore.as_retriever(),
    subject_id="alice",  # Fixed user
    ...
)
chain = retriever | prompt | llm

Pattern 2: SpiceDBAuthFilter (reusable)

auth = SpiceDBAuthFilter(...)
chain = retriever | auth | prompt | llm

# Same chain, different users
await chain.ainvoke("question", config={"configurable": {"subject_id": "alice"}})
await chain.ainvoke("question", config={"configurable": {"subject_id": "bob"}})

Pattern 3: LangGraph Node (stateful)

graph.add_node("authorize", create_auth_node(...))
# Authorization metrics available in state['auth_results']

Pattern 4: Agent Tool (agentic)

tools = [SpiceDBPermissionTool(...)]
agent = create_agent(llm, tools, system_prompt="You are a helpful assistant.")
# Agent can check "Can user alice delete document 123?" and explain the result

Installation

pip install langchain-spicedb

Optional Dependencies

# Install with LangChain support
pip install langchain-spicedb[langchain]

# Install with LangGraph support
pip install langchain-spicedb[langgraph]

# Install everything (recommended)
pip install langchain-spicedb[all]

Development Installation

git clone https://github.com/authzed/langchain-spicedb.git
cd langchain-spicedb
pip install -e ".[all,dev]"

Quick Start

1. Start SpiceDB

docker run --rm -p 50051:50051 authzed/spicedb serve \
    --grpc-preshared-key "sometoken" \
    --grpc-no-tls

2. Define Schema and Permissions

from authzed.api.v1 import Client, WriteSchemaRequest
from grpcutil import insecure_bearer_token_credentials

client = Client("localhost:50051", insecure_bearer_token_credentials("sometoken"))

schema = """
definition user {}

definition article {
    relation viewer: user
    permission view = viewer
}
"""

await client.WriteSchema(WriteSchemaRequest(schema=schema))

3. Use in LangChain

from langchain_spicedb import SpiceDBAuthFilter
from langchain_core.runnables import RunnableParallel, RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# Initialize auth filter
auth = SpiceDBAuthFilter(
    spicedb_endpoint="localhost:50051",
    spicedb_token="sometoken",
    subject_type="user",
    resource_type="article",
    resource_id_key="article_id",
    permission="view",
)

# Build chain once
chain = (
    RunnableParallel({
        "context": retriever | auth,  # Authorization happens here
        "question": RunnablePassthrough(),
    })
    | prompt
    | llm
    | StrOutputParser()
)

# Pass user at runtime - reuse same chain for different users
answer = await chain.ainvoke(
    "Your question?",
    config={"configurable": {"subject_id": "alice"}}
)

4. Use in LangGraph

from langgraph.graph import StateGraph, END
from langchain_spicedb import create_auth_node, RAGAuthState

graph = StateGraph(RAGAuthState)

# Add nodes
graph.add_node("retrieve", retrieve_node)
graph.add_node("authorize", create_auth_node(
    spicedb_endpoint="localhost:50051",
    spicedb_token="sometoken",
    resource_type="article",
    resource_id_key="article_id",
))
graph.add_node("generate", generate_node)

# Wire it up
graph.set_entry_point("retrieve")
graph.add_edge("retrieve", "authorize")
graph.add_edge("authorize", "generate")
graph.add_edge("generate", END)

# Run
app = graph.compile()
result = await app.ainvoke({
    "question": "What is SpiceDB?",
    "subject_id": "alice",
})

Documentation

  • Configuration Guide - Detailed configuration options, metadata requirements, and error handling
  • LangGraph Guide - Advanced LangGraph patterns, custom state, and visualization
  • Examples - Complete working examples and tutorials
  • Testing Guide - Running tests and integration testing

Components

SpiceDBRetriever

Wraps any LangChain retriever with SpiceDB authorization:

from langchain_spicedb import SpiceDBRetriever

retriever = SpiceDBRetriever(
    base_retriever=vector_store.as_retriever(),
    subject_id="alice",
    spicedb_endpoint="localhost:50051",
    spicedb_token="sometoken",
    resource_type="article",
    resource_id_key="article_id",
)

docs = await retriever.ainvoke("query")

SpiceDBPermissionTool

LangChain tool for agents to check permissions:

from langchain_spicedb import SpiceDBPermissionTool

tool = SpiceDBPermissionTool(
    spicedb_endpoint="localhost:50051",
    spicedb_token="sometoken",
    subject_type="user",
    resource_type="article",
)

result = tool.invoke({
    "subject_id": "alice",
    "resource_id": "doc123",
    "permission": "view"
})
# Returns: "true" or "false"

SpiceDBBulkPermissionTool

Same as SpiceDBPermissionTool but check permissions for multiple resources at once:

from langchain_spicedb import SpiceDBBulkPermissionTool

tool = SpiceDBBulkPermissionTool(
    spicedb_endpoint="localhost:50051",
    spicedb_token="sometoken",
    subject_type="user",
    resource_type="article",
)

result = tool.invoke({
    "subject_id": "alice",
    "resource_ids": "doc1,doc2,doc3",
    "permission": "view"
})
# Returns: "alice can access: doc1, doc2" or "alice cannot access any..."

Performance

  • Native Bulk API: Uses SpiceDB's CheckBulkPermissionsRequest for optimal performance
  • Single API Call: All permission checks happen in one request, not N individual calls
  • Async Operations: All operations are async for better performance

Testing

# Run unit tests
pytest tests/unit_tests/

# Run integration tests (requires SpiceDB)
SPICEDB_ENDPOINT=localhost:50051 SPICEDB_TOKEN=sometoken pytest tests/integration_tests/

# With coverage
pytest tests/ --cov=langchain_spicedb

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Add tests for new functionality
  4. Submit a pull request

License

Apache-2.0 License

Related Projects


Need help? Check out the examples or open an issue on GitHub.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

langchain_spicedb-0.1.1.tar.gz (21.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

langchain_spicedb-0.1.1-py3-none-any.whl (22.3 kB view details)

Uploaded Python 3

File details

Details for the file langchain_spicedb-0.1.1.tar.gz.

File metadata

  • Download URL: langchain_spicedb-0.1.1.tar.gz
  • Upload date:
  • Size: 21.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for langchain_spicedb-0.1.1.tar.gz
Algorithm Hash digest
SHA256 da6522989e9452e9230d9235295a01cf7a885c6d089aae6b3ca3d41b767a32ad
MD5 2a90b2d88f059506ee054fbc2d8bf874
BLAKE2b-256 6d60f34ba08b3ad9037b972a2b658e0b1f51c8ef30349b461f1cadf2d360c557

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_spicedb-0.1.1.tar.gz:

Publisher: publish-to-pypi.yml on authzed/langchain-spicedb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file langchain_spicedb-0.1.1-py3-none-any.whl.

File metadata

File hashes

Hashes for langchain_spicedb-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 99be22621dc2cc2056d1869d8f2441901add6c14ec95492837f26b26b28f8d09
MD5 b6b54984e7a23c07e9f607afbda8b128
BLAKE2b-256 6afe81c734267fe23946e97afa5601c39a23e0eca6ffe972e8d34679aa48bda9

See more details on using hashes here.

Provenance

The following attestation bundles were made for langchain_spicedb-0.1.1-py3-none-any.whl:

Publisher: publish-to-pypi.yml on authzed/langchain-spicedb

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page