( Authentication and authorization )

JWT authentication and RBAC for Python APIs

austial.auth gives you the primitives for authenticating requests: password hashing, JWT access tokens, TOTP multi-factor authentication and a refresh-token contract. A guard verifies bearer tokens before your handler runs. You bring the user model and persistence.

What austial.auth provides

  • Argon2id password hashing, verified in constant time through argon2-cffi.
  • Short-lived 15-minute JWT access tokens, with a 32-character minimum secret enforced at startup.
  • Opaque, rotating refresh tokens with server-side revocation and per-user bulk revoke.
  • TOTP for multi-factor authentication.
  • An AuthGuard that verifies the Authorization: Bearer header on every request.

Guarding routes

Apply AuthGuard to a controller, or register it globally. CurrentUser() gives a handler the authenticated principal, and @Public() opts a route out. Nothing runs unauthenticated unless you say so.

from austial import Controller, Get, UseGuards
from austial.auth import AuthGuard, CurrentUser, Public


@Controller("/me")
@UseGuards(AuthGuard)
class MeController:
    @Get()
    def me(self, user=CurrentUser()):
        return {"id": user.subject, "claims": user.claims}

    @Public()
    @Get("/robots.txt")
    def robots(self):
        return "User-agent: *\nDisallow:"

Roles and permissions

austial.authz adds role and permission checks on top of authentication, as guards and as programmatic checks inside a handler. Claims are populated at login, so the same token carries what the guard needs to decide.

Where the design comes from

The docs map each part of auth and authorization to the OWASP ASVS and OWASP API Security Top 10 controls it targets. Use that mapping as input to your own review, since your threat model and deployment are specific to you.

Frequently asked questions

Does Austial define my user model?

No. It provides strategies and a guard, and you wire them to your own user entity and persistence.

How are passwords stored?

Passwords are hashed with Argon2id, using OWASP-2024 parameters, through argon2-cffi.

Can I use RS256 instead of HS256?

The docs describe a 32-character minimum HS256 secret enforced at startup, and RS256 as a one-line change.

Go deeper in the docs

( Keep reading )

( Click. Copy. Build. )

Seeing “command not found”? Run uv tool update-shell, then open a new terminal. Details