Skip to main content

edwh-auth-rbac

Role-Based Access Control (RBAC) library with recursive memberships for Python applications.

Overview

This library implements a comprehensive RBAC system that supports:

  • Users, groups, and items as identities
  • Recursive group memberships (groups can contain other groups)
  • Time-bound permissions with start/end dates
  • Wildcard permissions (* for all privileges, all identities, or all targets)
  • Password hashing with HMAC-SHA512 and per-entry random salts

Mental Model

The system is built around three core concepts:

  1. Identities: Users (people), Groups (collections), and Items (resources)
  2. Memberships: Direct relationships between identities (who belongs to what)
  3. Permissions: Granted privileges on targets with time constraints

Key Features

  • Recursive membership resolution through database views
  • Efficient permission checking using JOINs with recursive membership views
  • Flexible identity lookup by email, ID, UUID, or name
  • Secure password storage with constant-time validation

Installation

pip install edwh-auth-rbac

Basic Usage

This requires a setup like the demo, see below for details, but this is how you would mostly use it in every day use:

from pydal import DAL
from edwh_auth_rbac import AuthRbac

# Initialize database
db = DAL('sqlite://storage.sqlite')

# Initialize RBAC
rbac = AuthRbac(db)
rbac.define_model(allowed_types=['user', 'group', 'item'], migrate=True)

Creating Users and Groups

# Create a group
admin_group = rbac.add_group(
    email="admin@example.com",
    name="Administrators",
    member_of=[]
)

# Create a user
user = rbac.add_user(
    email="john@example.com",
    firstname="John",
    fullname="John Doe",
    password="secure_password",
    member_of=[admin_group['object_id']]  # Add user to admin group
)

Adding Permissions

# Grant read permission to a user on a resource
rbac.add_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read"
)

# Grant write permission to a group (affects all members)
rbac.add_permission(
    identity_key=admin_group['object_id'],
    target_oid="document_123",
    privilege="write"
)

Checking Permissions

# Check if user has permission
has_read = rbac.has_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read"
)

print(f"User has read permission: {has_read}")

Advanced Features

Recursive Group Memberships

Groups can contain other groups, creating a hierarchy:

# Create nested groups
root_group = rbac.add_group(email="root@example.com", name="Root", member_of=[])
middle_group = rbac.add_group(email="middle@example.com", name="Middle", member_of=[root_group['object_id']])
leaf_group = rbac.add_group(email="leaf@example.com", name="Leaf", member_of=[middle_group['object_id']])

# Add user to leaf group
user = rbac.add_user(
    email="user@example.com",
    firstname="User",
    fullname="Test User",
    password="password",
    member_of=[leaf_group['object_id']]
)

# User now has permissions granted to any of the parent groups

Time-Bound Permissions

Permissions can be granted for specific time periods:

import datetime as dt

rbac.add_permission(
    identity_key=user['object_id'],
    target_oid="document_123",
    privilege="read",
    starts=dt.datetime(2023, 1, 1),
    ends=dt.datetime(2023, 12, 31)
)

Edge Cases and Assumptions

  • Circular group memberships are prevented by the recursive view logic
  • Non-existent targets in permissions are allowed (flexible resource modeling)
  • Time-bound permissions with precise datetime validation
  • Wildcard permissions that grant broad access rights (using "*")
  • Case-insensitive email handling
  • Automatic cleanup of related records when identities are removed
  • Passwords are stored securely with HMAC-SHA512 and per-entry random salts
  • Group names can be used as lookup keys for groups
  • Email addresses needn't be unique across different identity types

Setup demo database

For your own application, you'd probably want to use your own migration tool or use ours. But you'd have a list of migrations where you will want to include these from the src/edwh_auth_rbac/migrations.py file

Prepare the migration:

cd your-demo-folder
mkdir flags
export MIGRATE_URI=sqlite://storage.sqlite
export FLAG_LOCATION=./flags

Execute the migration:

$ migrate src/edwh_auth_rbac/migrations.py 
testing migrate lock file with the current version
Using lock file:  flags/migrate-e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855.complete
Using argument src/edwh_auth_rbac/migrations.py as a reference to the migrations file.
importing migrations from src/edwh_auth_rbac/migrations.py
starting migrate hook
2 migrations discovered
table not found, starting database restore
RECOVER: attempting recovery from a backup
RECOVER_DATABASE_FROM_BACKEND started 
RECOVER: /data/database_to_restore.NOTFOUND not found. Starting from scratch.
test: rbac_tables
run:  rbac_tables
ran:  rbac_tables successfully (0.01s wall, 0.00s CPU)
test: rbac_views
run:  rbac_views
ran:  rbac_views successfully (0.00s wall, 0.00s CPU)
migration completed successfully, marking success.

Execute the example.py demo:

$ python3 example.py 
=== Creating Users and Groups and Documents ===
Created document item: {'object_id': '208247a1-cf2f-4f4e-a0c9-3edc813a78b6', 'email': 'document@example.com', 'name': 'Test Document'}
Created admin group: {'object_id': '481c6a16-672f-43b7-ad71-2b1830a3dc09', 'email': 'admin@example.com', 'name': 'Administrators'}
Created user: {'object_id': 'c797b2da-47b4-42a4-ab1d-2c0b6150555f', 'email': 'john@example.com', 'firstname': 'John', 'fullname': 'John Doe'}

=== Adding Permissions ===
Granted read permission to user on document_123
Granted write permission to admin group on document_123

=== Checking Permissions ===
User has read permission: True
User has write permission: True

=== Example completed successfully! ===

Database Schema

The library creates the following tables:

  • identity: Core identity records with object_id, type, and credentials
  • membership: Direct membership relationships between identities
  • permission: Time-bound privilege grants from identity to target
  • recursive_memberships: View showing all indirect memberships
  • recursive_members: View showing all indirect members

API Reference

For detailed API documentation, see the docstrings in the source code:

  • AuthRbac class in src/edwh_auth_rbac/rbac.py
  • Model functions in src/edwh_auth_rbac/model.py

Download files

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

Source Distribution

edwh_auth_rbac-2.0.1.tar.gz (76.4 kB view details)

Uploaded Source

Built Distribution

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

edwh_auth_rbac-2.0.1-py3-none-any.whl (24.7 kB view details)

Uploaded Python 3

File details

Details for the file edwh_auth_rbac-2.0.1.tar.gz.

File metadata

  • Download URL: edwh_auth_rbac-2.0.1.tar.gz
  • Upload date:
  • Size: 76.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for edwh_auth_rbac-2.0.1.tar.gz
Algorithm Hash digest
SHA256 46eb9d737de85228ed3173b5b6400a41e51af5515c52581b7b3644392482720a
MD5 5d75e2da3e14c75a1a5833e8bea50683
BLAKE2b-256 9d7011d3365b408d1f1dc8a44159c51536f285e6f472e68c3b8f7eef7b10d018

See more details on using hashes here.

File details

Details for the file edwh_auth_rbac-2.0.1-py3-none-any.whl.

File metadata

  • Download URL: edwh_auth_rbac-2.0.1-py3-none-any.whl
  • Upload date:
  • Size: 24.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.12.2 {"installer":{"name":"uv","version":"0.12.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.3","id":"zena","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for edwh_auth_rbac-2.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 889fd88e91ff4851a1c5321017e1480ca1dae0509f9f6c4b46ba3a2408b4fdd8
MD5 1ba93addfef2fd1cfa60e3001f41911a
BLAKE2b-256 c75f72865be845481cc14c22eec77f1d04d32bea5873b47fe7bf8500745652b6

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 Sentry Error logging StatusPage Status page