Skip to main content

auth — RBAC authorization service

CI Python License: MIT

Role-based access control over HTTP. auth answers one question — may user X do Y — so your services don't reinvent roles and permissions.

It is authorization, not authentication: it does not log anyone in, store passwords, or issue tokens. It trusts that the caller already knows who the user is, and decides what they may do. Model: user → (member of) → role → (holds) → permission.

Quickstart

Your client key is any UUID4 — it is also your private, isolated namespace. Generate one, keep it secret, and reuse it for every call. A role must exist before you add members or permissions to it.

KEY=$(python3 -c "import uuid; print(uuid.uuid4())")
BASE=https://auth.rodmena.app

curl -X POST -H "Authorization: Bearer $KEY" $BASE/api/role/engineers
curl -X POST -H "Authorization: Bearer $KEY" $BASE/api/permission/engineers/deploy
curl -X POST -H "Authorization: Bearer $KEY" $BASE/api/apikeys/user/alice
curl -X POST -H "Authorization: Bearer $KEY" $BASE/api/membership/alice/engineers
curl        -H "Authorization: Bearer $KEY" $BASE/api/has_permission/alice/deploy
# -> {"success": true, "data": {"has_permission": true}, ...}

Why the apikeys call is in there. Since 3.0.0 a namespace created from a brand-new key is strict: a user must hold an API key in your namespace before it can be given a role. Omit that line and the membership call answers 409 {"reason": "user_not_key_backed", "result": false} — a permanent refusal, so retrying never helps. You need not keep the returned secret if you only want the identity to exist.

If your users can never hold auth API keys (you authenticate them yourself and your "users" are opaque ids), opt the namespace out once and skip that step forever:

curl -X PUT -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
     -d '{"strict_users": false}' $BASE/api/settings

The opt-out is audited, per-tenant, and supported indefinitely. Namespaces created before 3.0.0 were grandfathered onto it, which is why existing integrations saw no change at upgrade.

With the Python client (pip install auth):

from auth import Client

with Client(api_key=KEY, service_url="https://auth.rodmena.app") as c:
    c.create_role("engineers")
    c.add_permission("engineers", "deploy")
    c.create_api_key("alice")                  # strict default since 3.0.0
    c.add_membership("alice", "engineers")
    c.user_has_permission("alice", "deploy")   # -> {... "has_permission": true}

Things to know before you write code

  • Writes can return HTTP 200 with {"result": false} (e.g. adding to a missing role). Check the result/data field, not just the status code.
  • Two response shapes — bare {"result": ...} and wrapped {"success", "data", ...}. The API reference says which per endpoint.
  • Errors below 2xx are HTML, not JSON. Branch on the status code first.
  • Python client: transport failures raise AuthTransportError (3.0.0). The 2.x answer-shaped error dict is gone — an outage can never be misread as a denial. Catch the exception and map it to your unavailable/503 path, never to a permission denial. The old raise_on_error constructor argument is a deprecated no-op, so 2.x code keeps constructing.
  • Reuse one key. A new key is a new empty namespace, not an error. Keep the key out of source control, logs, and URLs — it is the only thing protecting your data. Rotate it with POST /api/keys/rotate if it leaks.
  • Per-user API keys (2.4.0): /api/apikeys/user/<user> (create/list), /api/apikeys/user/<user>/<key_id> (revoke), /api/apikeys/validate. auth mints rak_... secrets for your users, shows each exactly once, stores only a hash, and validates them inside your namespace — an identity UI fronts the lifecycle, backends validate then use the RBAC checks. Client methods: create_api_key, list_api_keys, revoke_api_key, validate_api_key, check_api_key_permission (validate + permission in one round trip), plus get_settings/set_strict_users. All of these also exist on the in-process Authorization wrapper for embedded consumers.
  • Strict user identity is the default for NEW tenants (3.0.0). A tenant namespace created after 3.0.0 requires key-backed users for authorization decisions (user_not_key_backed answers; key-less membership grants answer 409) — create the user's API key first, then grant roles. Every tenant that existed before 3.0.0 was grandfathered with an explicit strict_users: false row (nothing changed for them at upgrade), and the audited per-tenant opt-out (PUT /api/settings {"strict_users": false}) survives indefinitely for validated machine-subject architectures. Details: docs/DEPRECATIONS.md.

Documentation

Doc What's in it
Live API reference — /docs · /llms.txt Every endpoint and exact response shape, served by the app (agent-friendly).
docs/ARCHITECTURE.md Design, components, request lifecycle, data model, permission-check and key-rotation flows, diagrams.
SECURITY.md Security model (tenant isolation, encryption, audit, rotation), threat notes, reporting.
MIGRATIONS.md Schema creation vs migrations, upgrade/rollback runbook.
CONTRIBUTING.md Local setup, tests (sqlite + postgres), lint/type-check, CI.
docs/ Full Sphinx docs (concepts, configuration, encryption, deployment, REST & Python usage).

When to use — and not

Use it for RBAC: named roles, permissions, group membership, and boolean "can user X do Y" gates for a service, CLI, or workflow engine.

Not for authentication (login/passwords/sessions/OAuth/JWT), fine-grained / attribute-based rules (owner-of-this-record, time-of-day, row-level tenancy — reach for an ABAC/policy engine), or air-gapped hot loops where a network hop per check is too costly (cache, or use the library in-process).

Development

python3.11 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev,ratelimit,migrations]"
make check   # ruff + mypy
make test    # sqlite suite
make test-postgres   # postgres integration (Docker), encryption on

See CONTRIBUTING.md for the full workflow. Licensed under the MIT License.

Metadata

Release files for auth 3.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for auth 3.5.0
File Size Uploaded Provenance
auth-3.5.0.tar.gz 135.5 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for auth 3.5.0
File Interpreter ABI Platform
auth-3.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 245.9 kB

Release files / auth-3.5.0.tar.gz

Download URL auth-3.5.0.tar.gz
Size 135.5 kB
Tags Source
SHA-256 checksum
How to use checksums
5994f8ee2c8b16515476072b7a744bb09fb0493a70ce35dbe8433705a2d3f7a5
BLAKE2b-256 checksum
How to use checksums
3f57fc0b53f9a4ddfd384a8dc6e3710ee2a50802c4f1421b35da05bc2e5f187a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / auth-3.5.0-py3-none-any.whl

Download URL auth-3.5.0-py3-none-any.whl
Size 110.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3e0a7ba8e7ebdce1d8095691fe88debf1eda1faaa5ee2570ac0f751ba08a54dd
BLAKE2b-256 checksum
How to use checksums
f3cfcf1ede44d57306bc3559ff210525157d021c757fa44acf09d7cc53fec145
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Security for auth 3.5.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

3.5.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page