Clean-architecture auth core for multiple Python frameworks
Project description
pkg-auth
Clean-architecture identity + ACL for multi-framework Python services. Handles JWT authentication (via Keycloak) and database-backed authorization (users, organizations, roles, permissions, memberships) in a single package with first-class support for FastAPI, Django, and Strawberry GraphQL.
v1.0 is a breaking change from v0.x. The old claim-based authorization model (
AccessContext,AccessRights,require_permissions) is replaced by a real ACL database. Seedocs/MIGRATION_v1.mdfor the upgrade guide.
Install
# Core (identity only — no DB deps)
pip install pkg-auth
# With ACL + FastAPI (most common for itqadem services)
pip install pkg-auth[acl-sqlalchemy,fastapi]
# With ACL + Django
pip install pkg-auth[acl-django,django]
# With optional Redis cache
pip install pkg-auth[cache-redis]
Quickstart (FastAPI)
from fastapi import Depends, FastAPI
from pkg_auth.authentication import IdentityContext
from pkg_auth.authorization import AuthContext
from pkg_auth.integrations.fastapi import (
create_authentication,
make_get_auth_context,
require_permission,
)
# --- Wire authentication + authorization ---
auth = create_authentication(
keycloak_base_url="https://auth.example.com",
realm="itqadem",
audience="courses-service",
)
# Mode B (consumer — the common case): pass resolve_user_use_case.
# Mode A (source-of-truth): pass sync_user_use_case instead. Exactly
# one of the two is required; passing both raises ValueError.
get_auth_context = make_get_auth_context(
get_identity=auth.get_identity,
resolve_user_use_case=resolve_user, # or: sync_user_use_case=sync_user (Mode A)
resolve_use_case=resolve,
organization_repo=org_repo,
)
app = FastAPI()
# --- Use in routes ---
@app.get("/courses/{id}")
async def get_course(
id: str,
bundle: tuple[IdentityContext, AuthContext] = Depends(
require_permission("course:view", get_auth_context=get_auth_context)
),
):
identity, auth_ctx = bundle
return {"course_id": id, "role": str(auth_ctx.role_name)}
See examples/itqadem_courses_app for a complete working example.
Architecture
pkg_auth/
authentication/ JWT validation → IdentityContext (identity only)
authorization/ Full ACL (users, orgs, roles, perms, memberships)
domain/ Pure entities, ports (Protocol), exceptions
application/use_cases/ Business logic (13 use cases)
adapters/
sqlalchemy/ Canonical schema + Alembic migration + repos
django_orm/ Mirror models (managed=False) + repos
cache/ InMemoryTTLCache / RedisCache + decorator
integrations/
fastapi/ Deps + require_permission + exception handlers
django/ Middleware + decorators
strawberry/ Context getter + permission classes
admin/ Keycloak admin client (user provisioning)
Layering rules: domain has zero external imports; application imports only domain; adapters import their framework; integrations import everything.
Documentation
- Authorization model — schema, permission catalog, roles, memberships
- Caching — InMemoryTTLCache, RedisCache, invalidation contract
- FastAPI Integration
- Django Integration
- Strawberry Integration
- Keycloak Admin
- Migration from v0.x
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pkg_auth-3.0.0.tar.gz.
File metadata
- Download URL: pkg_auth-3.0.0.tar.gz
- Upload date:
- Size: 67.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e6e413d91a4d46a73aa8c1a4682d46dfd7231e3291de8c5a55deb4618a149bd7
|
|
| MD5 |
ae59a4252204fe7b74e4f771491569f9
|
|
| BLAKE2b-256 |
b3885ae12c67c5d4d610686c9957f7d7d74090423a2764c1467923c2bf0a89b8
|
Provenance
The following attestation bundles were made for pkg_auth-3.0.0.tar.gz:
Publisher:
publish.yml on fritill-team/fri_pkg_auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkg_auth-3.0.0.tar.gz -
Subject digest:
e6e413d91a4d46a73aa8c1a4682d46dfd7231e3291de8c5a55deb4618a149bd7 - Sigstore transparency entry: 1891369935
- Sigstore integration time:
-
Permalink:
fritill-team/fri_pkg_auth@45e1c745687e852b28614e08befb7866bbd10a9f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fritill-team
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@45e1c745687e852b28614e08befb7866bbd10a9f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file pkg_auth-3.0.0-py3-none-any.whl.
File metadata
- Download URL: pkg_auth-3.0.0-py3-none-any.whl
- Upload date:
- Size: 112.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f21488a47023a3637510ae77bc83f9a7a6bab8941a16c635e447ec55954414ff
|
|
| MD5 |
d5113fc96311cbe430312d3005df0387
|
|
| BLAKE2b-256 |
54c09a0556563ccc5f1b1eb9329b94f46afd12ce0a6799ff205fd7f44ff1b898
|
Provenance
The following attestation bundles were made for pkg_auth-3.0.0-py3-none-any.whl:
Publisher:
publish.yml on fritill-team/fri_pkg_auth
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pkg_auth-3.0.0-py3-none-any.whl -
Subject digest:
f21488a47023a3637510ae77bc83f9a7a6bab8941a16c635e447ec55954414ff - Sigstore transparency entry: 1891370155
- Sigstore integration time:
-
Permalink:
fritill-team/fri_pkg_auth@45e1c745687e852b28614e08befb7866bbd10a9f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fritill-team
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@45e1c745687e852b28614e08befb7866bbd10a9f -
Trigger Event:
workflow_dispatch
-
Statement type: