Skip to main content

Recursive Memberships and Permissions for the Education Warehouse Authentication System

Project description

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

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

edwh_auth_rbac-0.9.0b1.tar.gz (70.0 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-0.9.0b1-py3-none-any.whl (22.5 kB view details)

Uploaded Python 3

File details

Details for the file edwh_auth_rbac-0.9.0b1.tar.gz.

File metadata

  • Download URL: edwh_auth_rbac-0.9.0b1.tar.gz
  • Upload date:
  • Size: 70.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.2","id":"zara","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-0.9.0b1.tar.gz
Algorithm Hash digest
SHA256 85298458014537e89ead532ddffa2c798878a98640352b3825e2eb579d0f8931
MD5 656c92e12eb7cd4f4fa89a4947c0c00c
BLAKE2b-256 68675d362e10db587029d95b19cf56f76ef921f58581bf996949813bf01e4a26

See more details on using hashes here.

File details

Details for the file edwh_auth_rbac-0.9.0b1-py3-none-any.whl.

File metadata

  • Download URL: edwh_auth_rbac-0.9.0b1-py3-none-any.whl
  • Upload date:
  • Size: 22.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.11 {"installer":{"name":"uv","version":"0.9.11"},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Linux Mint","version":"22.2","id":"zara","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-0.9.0b1-py3-none-any.whl
Algorithm Hash digest
SHA256 fe3837552b4b44bbb86e313ffef442f3a11f91072192a6504345e24393009e00
MD5 2c623b3122ab63e5b43716f366a61bed
BLAKE2b-256 5129678d78dd85efc8285b85f5242591593def8f401e506d437c9a040304b869

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