Skip to main content

Relationship-Based Access Control (ReBAC) engine for Python.

Project description

SpiceAuth 🌶️

SpiceAuth is a lightweight, high-performance ReBAC (Relationship-Based Access Control) engine for Python, inspired by Google's Zanzibar paper.

In traditional RBAC systems, you check if a user has a specific "role". In ReBAC, permissions are determined by tracing relationships in a graph. SpiceAuth allows you to define complex hierarchies (like Folders -> Documents, or Organizations -> Teams -> Users) without hardcoding business logic into your application code.

Installation

Install SpiceAuth via pip. It requires Python 3.9+.

pip install spiceauth

If you plan to use the production-ready asynchronous SQLAlchemy backend, install the required dependencies:

pip install spiceauth[dev] # Includes aiosqlite, pytest for testing
# For production, install your preferred async DB driver, e.g., asyncpg

Core Concepts

SpiceAuth models permissions using a few simple concepts:

  1. Subjects: The entity taking an action (e.g., user:amrah, group:dev-team).
  2. Objects: The resource being accessed (e.g., document:roadmap-2026, project:alpha).
  3. Relations: The type of link between a subject and an object (e.g., viewer, editor, member, parent).
  4. RelationTuples: A concrete statement linking a subject, relation, and object.
  5. Rules: Dynamic schemas that compute permissions based on relations (e.g., "The editor of a document's parent project is automatically an editor of the document").

Quickstart (Memory Backend)

For testing or simple applications, you can use the in-memory backend. SpiceAuth is fully asynchronous.

import asyncio
from spiceauth import SpiceEngine, RelationTuple

async def main():
    # 1. Initialize the engine with the default Memory backend
    auth = SpiceEngine()

    # 2. Write relation tuples
    await auth.write_tuples([
        # Amrah is a member of the dev-team
        RelationTuple(subject="user:amrah", relation="member", object="group:dev-team"),
        
        # The dev-team is the editor of Project Alpha
        RelationTuple(subject="group:dev-team", relation="editor", object="project:alpha"),
        
        # Project Alpha is the parent of the Roadmap Document
        RelationTuple(subject="project:alpha", relation="parent", object="document:roadmap-2026")
    ])

    # 3. Define a Rule for computed relationships (Inheritance)
    # Rule: If a user is an 'editor' of a document's 'parent', they are an 'editor' of the document.
    await auth.define_rule(
        object_type="document",
        relation="editor",
        computed_userset="object.parent.editor" 
    )

    # 4. Check permissions
    is_allowed = await auth.check(
        subject="user:amrah", 
        relation="editor", 
        object="document:roadmap-2026"
    )
    
    print(f"Can Amrah edit the document? {is_allowed}") # Output: True

if __name__ == "__main__":
    asyncio.run(main())

Production Usage (SQLAlchemy Backend)

For production, you should use a persistent database. SpiceAuth comes with an asynchronous SQLAlchemy backend built on top of sqla-async-orm-queries.

import asyncio
from sqlalchemy.ext.asyncio import create_async_engine, async_sessionmaker
from sqla_async_orm_queries import Model

from spiceauth import SpiceEngine
from spiceauth.backends.sqlalchemy import SQLAlchemyBackend

async def init_db():
    # Use your production async database URL here (e.g., PostgreSQL with asyncpg)
    engine = create_async_engine("sqlite+aiosqlite:///:memory:")
    
    # Create tables
    async with engine.begin() as conn:
        await conn.run_sync(Model.metadata.create_all)
    
    # Initialize the session maker for the ORM
    SessionLocal = async_sessionmaker(
        autocommit=False, 
        autoflush=False, 
        expire_on_commit=False, 
        bind=engine
    )
    Model.init_session(SessionLocal)

async def main():
    await init_db()
    
    # Initialize the engine with SQLAlchemy backend
    auth = SpiceEngine(backend=SQLAlchemyBackend())
    
    # Now you can use auth.write_tuples() and auth.check() just like the memory backend!
    # They will be safely persisted in your relational database.

if __name__ == "__main__":
    asyncio.run(main())

How It Works Under The Hood

When you call auth.check(), SpiceAuth performs a Graph traversal (DFS) to resolve permissions:

  1. Direct Match: Does the tuple (subject, relation, object) exist in the DB?
  2. Implicit Group Membership: Does the subject have a member relation to a group that has the requested relation?
  3. Computed Rules: Does the object's type have a rule (like object.parent.editor)? If so, the engine fetches the parent object and recursively checks if the subject is an editor of that parent.

Infinite loops and circular dependencies are automatically caught and prevented during traversal.

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

spiceauth-1.0.1.tar.gz (7.8 kB view details)

Uploaded Source

Built Distribution

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

spiceauth-1.0.1-py3-none-any.whl (7.1 kB view details)

Uploaded Python 3

File details

Details for the file spiceauth-1.0.1.tar.gz.

File metadata

  • Download URL: spiceauth-1.0.1.tar.gz
  • Upload date:
  • Size: 7.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.9.25 Linux/6.17.0-1018-azure

File hashes

Hashes for spiceauth-1.0.1.tar.gz
Algorithm Hash digest
SHA256 86694865d4d0678e7cf9e12dd2bb84d183948b733909fabebde40401b587db75
MD5 e02a2c3ff869e35fb3cb605731e3e1b8
BLAKE2b-256 cb2568d211045b0b2f679fb69d419c9c8db58f08e2bcf7a58fe03f0131b6fefe

See more details on using hashes here.

File details

Details for the file spiceauth-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: spiceauth-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.9.25 Linux/6.17.0-1018-azure

File hashes

Hashes for spiceauth-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1cb7658e5a143e29c1cb744813fe39cda4269659e765ff1ce4f19721ee68ad63
MD5 e1fdbb38cd54108e4670c75730d02735
BLAKE2b-256 529fc93387560432263fc3554188ca743911e95672c322dca34deffe93c3fe58

See more details on using hashes here.

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