Track A (FERPA/COPPA) application-layer authorization resolver (PDP+PEP) — Python sibling of @superbuilders/authz for bridge's Python tier.
Project description
superbuilders-authz (Python)
Part of the
superbuilders/timeback-authzmonorepo (python/). It shares the cross-language conformance vectors in../conformance/vectors.jsonwith the TS package — policy changes must update the vectors and pass both suites.
Track A (FERPA/COPPA) application-layer authorization resolver — the Python sibling of @super-oar/authz, built for bridge's Python tier (TA-PEP-03 / TA-PEP-10, WS3 shadow-authz seam). Faithful port: same gate order, same verdicts, same reasons, same shadow-log shape — both languages' [authz-shadow] logs aggregate identically on the deny-storm dashboards.
- Pure stdlib, no DB required, no native deps → runs anywhere (Lambda, containers, cron workers).
- Application-layer first.
decide()returns a decision + a filter spec and works with no database — because most consumers read student data over REST / MySQL / DynamoDB, not a Postgres the package can attach to. RLS/GUC enforcement is a later phase and is intentionally not in this package. - Decision core is swappable (ADR-11): SQL capability merge now → Cedar/OpenFGA later, same surface.
- Import package:
superbuilders_authz. Python>= 3.11(bridge pins 3.12).
API
await decide(DecideInput(...), deps) → Decision(verdict, reason, filter?, mask_fields?)— the core. Ordered gates (tenant → role active+window → read-only → capability+scope → sensitivity → consent → elevation); first-fail-denies;dual_read/shadowdowngrade towould_*(deploying denies nobody). Omitresourcefor a list read → returns afilter(allowed org/user/class ids) to constrain your query.- Shadow seam (the WS3 deliverable):
shadow_compare(...)runsdecide()beside your existing check and logs the comparison. Never raises, never changes the request outcome (returnsNoneon any error).build_coarse_principal(...)/coarse_role_capabilities(role)build an INTERIM principal from the coarse OneRoster role until WS5 seedsrole_capabilities(fail-closed on unknown roles). - Guards (raise
AuthzError(403) in enforce, returnwould_*in shadow):authorize,assert_parent_child_access,assert_teacher_class_access,assert_school_access,assert_can_read(object-level BOLA),require_admin/require_teacher_or_admin/require_parent_or_guardian. - Capability merge:
merge_capabilities(role_capabilities ⊕ user_capability_grants, deny-precedence, NULL tier → most-restrictive, M2Mclient_appkeys). - Consent:
classify_consent_boundary,method_satisfies_basis/is_vpc(COPPA under-13 VPC split),evaluate_consent/mask_fields_for(opt-out / Sec-GPC hard deny; special_pops + McKinney-Vento + directory-opt-out field masking). - Escalation:
can_grant— the TA-PEP-15 no-escalation invariant (roles.manage precondition, in-set at equal-or-lesser scope, dual-control oncompliance_gated).
You inject your store + identity (the per-app glue)
from superbuilders_authz import DecideDeps, ScopeResult
async def resolve_scope(scope, subject) -> ScopeResult:
... # your enrollments / guardianship_links / orgs query -> ScopeResult
async def consent_ok(child_sourced_id: str, purpose: str, tenant_id: str) -> bool:
... # your consent_records lookup -> bool
deps = DecideDeps(resolve_scope=resolve_scope, consent_ok=consent_ok)
- Build
Principalfrom your already-verified identity (Cognito JWT / Clerk / Supabase). Never trust an IdP group/claim/metadata for capabilities — resolve them from the authoritative store. Usesystem=Truefor non-HTTP workers (cron/sync),read_only=Truefor read-only service accounts. - Postgres consumers can use the bundled adapter instead of hand-writing the glue:
create_scope_resolver(q)/create_consent_checker(q)over any driver wrapped to satisfy theAuthzQueryprotocol (asyncpg/psycopg/supabase).
Shadow usage (WS3)
from superbuilders_authz import build_coarse_principal, shadow_compare, ResourceRef, ScopeResult
subject = build_coarse_principal(user_sourced_id="T1", role="teacher", org_sourced_id="S1")
await shadow_compare(
subject=subject,
action="academics.read",
resource=ResourceRef(kind="student", owner_sourced_id=student_id, tenant_id=subject.tenant_id),
scope=ScopeResult(user_sourced_ids=my_already_resolved_student_ids), # relationship truth the app already has
current_allowed=existing_check_passed, # what your current authorization decided
label="lalilo.rostered_students", # stable call-site label for the dashboards
)
Emits (identical to the TS package — same prefix, same field names, same order):
[authz-shadow] {"label":"lalilo.rostered_students","action":"academics.read","role":"teacher","owner":"stu1","current":"allow","would":"would_allow","agree":true,"reason":"ok","maskFields":[]}
Test / build
python3 -m venv .venv
.venv/bin/pip install -e '.[dev]'
.venv/bin/pytest # capability merge + RC fail-closed regressions + shadow would_* downgrade + log-shape parity
Not covered (mirrors the TS package)
RLS / GUC enforcement, the signed impersonation grant, break-glass MFA activation, and the biometric short-lived VPC capability token are app/infra-side deliverables, not in this package.
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 superbuilders_authz-0.0.4.tar.gz.
File metadata
- Download URL: superbuilders_authz-0.0.4.tar.gz
- Upload date:
- Size: 30.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 |
cb3dca5ec66749597ac818af3c122abe72f7da9979d48717312b3854147fc8ef
|
|
| MD5 |
b32c3e22f6823098dba935eb0815b0f3
|
|
| BLAKE2b-256 |
22c403d3929f73384a51045fea7059848b3fbba2b04c9ccc10ce7675f16b6314
|
Provenance
The following attestation bundles were made for superbuilders_authz-0.0.4.tar.gz:
Publisher:
publish-python.yml on superbuilders/timeback-authz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
superbuilders_authz-0.0.4.tar.gz -
Subject digest:
cb3dca5ec66749597ac818af3c122abe72f7da9979d48717312b3854147fc8ef - Sigstore transparency entry: 2134167752
- Sigstore integration time:
-
Permalink:
superbuilders/timeback-authz@2d31b92aa174d87efba527e1e6f21ff68af3ad7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/superbuilders
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@2d31b92aa174d87efba527e1e6f21ff68af3ad7d -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file superbuilders_authz-0.0.4-py3-none-any.whl.
File metadata
- Download URL: superbuilders_authz-0.0.4-py3-none-any.whl
- Upload date:
- Size: 25.8 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 |
3ad2dc39363bd938eec73cda85ece5b1724ee374981f8deff8d404b78a21dcce
|
|
| MD5 |
94d17e5c99b1553acee4399923243a82
|
|
| BLAKE2b-256 |
a4cac79b455ddb80980211b6801281b317086d70bc870f943067bbae54d34cfa
|
Provenance
The following attestation bundles were made for superbuilders_authz-0.0.4-py3-none-any.whl:
Publisher:
publish-python.yml on superbuilders/timeback-authz
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
superbuilders_authz-0.0.4-py3-none-any.whl -
Subject digest:
3ad2dc39363bd938eec73cda85ece5b1724ee374981f8deff8d404b78a21dcce - Sigstore transparency entry: 2134168365
- Sigstore integration time:
-
Permalink:
superbuilders/timeback-authz@2d31b92aa174d87efba527e1e6f21ff68af3ad7d -
Branch / Tag:
refs/heads/main - Owner: https://github.com/superbuilders
-
Access:
private
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-python.yml@2d31b92aa174d87efba527e1e6f21ff68af3ad7d -
Trigger Event:
workflow_dispatch
-
Statement type: