Skip to main content

No project description provided

Project description

🛡️ GuardNet

GuardNet is a graph-based, type-safe ReBAC (Relationship-Based Access Control) engine for Python 3.11+.

Inspired by distributed state machine patterns, GuardNet allows you to model complex authorization logic as a directed graph of Python classes. It solves the "spaghetti if-statement" problem in authorization by using recursive delegation, short-circuiting logical gates, and request-scoped memoization.


✨ Key Features

  • Code as Truth: Policies are standard Python classes. No custom DSLs, JSON, or YAML logic.
  • Context Awareness: Use Pydantic models to define exactly what data is needed for a specific check.
  • Relationship-Based (ReBAC): Easily model inheritance (e.g., Document -> Folder -> Organization) using the Delegate pattern.
  • Memoization: Identical checks within the same request context are executed only once, saving database overhead.
  • Short-Circuiting: AnyOf (OR) and AllOf (AND) gates stop execution as soon as a result is determined.
  • Static Validation: Detect circular dependencies and connectivity issues in your authorization graph before you deploy.

🚀 Quick Start

1. Define your Context and Nodes

Nodes are the building blocks of your policy. They receive a typed context and return a Decision.

from pydantic import BaseModel
from guardnet import GuardNode, Effect, AnyOf, PolicyEngine

class AuthCtx(BaseModel):
    user_id: str
    resource_id: str

class IsAdmin(GuardNode[AuthCtx]):
    async def evaluate(self, ctx: AuthCtx):
        # Direct boolean logic
        return Effect.ALLOW if ctx.user_id == "admin-1" else Effect.DENY

class IsOwner(GuardNode[AuthCtx]):
    async def evaluate(self, ctx: AuthCtx):
        # You can perform async DB calls here
        return Effect.ALLOW if ctx.resource_id == "owner-res" else Effect.DENY

class RootPolicy(GuardNode[AuthCtx]):
    async def evaluate(self, ctx: AuthCtx):
        # Logical composition with short-circuiting
        return AnyOf(branches=[IsAdmin, IsOwner])

2. Execute the Check

The PolicyEngine manages the evaluation and handles request-scoped caching.

engine = PolicyEngine(nodes=[RootPolicy, IsAdmin, IsOwner])

allowed = await engine.check(
    start_node=RootPolicy, 
    context=AuthCtx(user_id="user-1", resource_id="owner-res")
)

if allowed:
    print("Access Granted!")

🛠️ Advanced: ReBAC and Inheritance

GuardNet shines when resources inherit permissions from parents. Use Delegate to switch contexts mid-evaluation.

class CheckDocument(GuardNode[DocCtx]):
    async def evaluate(self, ctx: DocCtx):
        # Look up the parent folder ID
        parent_id = await db.get_parent_folder(ctx.doc_id)
        
        # Delegate checking to the Folder policy with a new context
        return Delegate(
            node_cls=CheckFolder,
            sub_context=FolderCtx(user_id=ctx.user_id, folder_id=parent_id)
        )

🔍 Static Analysis

Prevent infinite loops or broken logic in your security graph by validating it at startup or in CI/CD.

from guardnet import GraphAnalyzer

# This will raise a RecursionError if a cycle is found
GraphAnalyzer.validate(RootPolicy, engine._registry)

⚖️ License

MIT

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

guardnet-0.1.3.tar.gz (4.4 kB view details)

Uploaded Source

Built Distribution

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

guardnet-0.1.3-py3-none-any.whl (5.5 kB view details)

Uploaded Python 3

File details

Details for the file guardnet-0.1.3.tar.gz.

File metadata

  • Download URL: guardnet-0.1.3.tar.gz
  • Upload date:
  • Size: 4.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for guardnet-0.1.3.tar.gz
Algorithm Hash digest
SHA256 36a6e7432771daad5ae5bdfbafe9d26d9696ba6c82a56fd72f56cae737b0670a
MD5 1519d2bd06d490cf577b2543ec88d857
BLAKE2b-256 95af30ec8bd7c8c8a50e675f9e5498cc1a56cab7ff89073caa01c9d8de172245

See more details on using hashes here.

File details

Details for the file guardnet-0.1.3-py3-none-any.whl.

File metadata

  • Download URL: guardnet-0.1.3-py3-none-any.whl
  • Upload date:
  • Size: 5.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.5

File hashes

Hashes for guardnet-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 41a0a8b67868b11166cebdad05488dc9ef1bd55027be02171423ae45ea9c9d70
MD5 6ccf51df1305b5681b35c88a3f31a026
BLAKE2b-256 d6b4874ac99658386dab9e262d9146afbfca11ad5436e5a9d3211e8e553d27d0

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