Guards¶
Custom user models must expose the typing protocols that match the guards you use—see
Types and protocols — Which protocol should my user model implement?
for a feature-to-protocol decision table (UserProtocol, GuardedUserProtocol,
RoleCapableUserProtocol, TotpUserProtocol).
Use these callables directly in Litestar guards=[...] lists. The role-guard
factories has_any_role(*roles) and has_all_roles(*roles) require an
authenticated active user, fail closed when request.user does not satisfy the
role-capable contract, and compare both configured roles and user roles with the
same normalization rules used by the model and manager layers (trimmed,
lowercased, deduplicated flat strings).
Permission guard factories use the same Litestar guard shape:
has_permission(*permissions)requires every listed permission.has_all_permissions(*permissions)is the explicit all-of alias.has_any_permission(*permissions)requires at least one listed permission.
They require an authenticated active role-capable user, resolve effective
permissions through the request-scope permission resolver, and raise
InsufficientPermissionsError / INSUFFICIENT_PERMISSIONS when access is denied.
Configured requirements must be concrete resource:action tokens. Granted
permissions may use resource:* or *; the configured superuser role resolves to
the global * grant.
API-key guards operate on ApiKeyContext from request.auth:
requires_api_keyaccepts only API-key-authenticated requests.has_scope(*scopes)requires every listed key scope and, when the key context was issued withscope_subset_check=True, still downscopes by the current user's authority.has_any_scope(*scopes)requires at least one listed key scope and, when the key context was issued withscope_subset_check=True, still downscopes by current user authority.requires_password_sessionrejects API-key callers and is used on self-service API-key create/update/revoke routes plus other credential-rotation boundaries.
Permission-shaped API-key scopes share the permission grammar and wildcard matcher:
reports:* grants reports:read, and * grants every concrete permission-shaped
scope. With scope_subset_check=True, the default scope authority requires those
delegated grants to be covered by the owning user's resolved permissions. Legacy
simple scopes without : keep the exact scopes-as-role-names check for migration.
from litestar import get
from litestar_auth.guards import (
has_all_permissions,
has_all_roles,
has_any_permission,
has_any_role,
has_scope,
is_verified,
requires_api_key,
)
@get("/billing", guards=[is_verified, has_any_role("admin", "billing")])
async def billing_dashboard() -> dict[str, bool]:
return {"ok": True}
@get("/finance", guards=[has_all_roles("admin", "billing")])
async def finance_dashboard() -> dict[str, bool]:
return {"ok": True}
@get("/posts", guards=[has_all_permissions("posts:read", "posts:write")])
async def posts_dashboard() -> dict[str, bool]:
return {"ok": True}
@get("/moderation", guards=[has_any_permission("posts:moderate", "comments:moderate")])
async def moderation_dashboard() -> dict[str, bool]:
return {"ok": True}
@get("/reports", guards=[requires_api_key, has_scope("reports:read")])
async def reports() -> dict[str, bool]:
return {"ok": True}
litestar_auth.guards
¶
Public authorization guard exports.
Guards enforce authentication and coarse account state (active, verified,
superuser) on Litestar routes. Role and permission guard factories build direct
guards=[...] callables for normalized authorization checks. All guards are
intended for route guards= lists and compose with application-specific
authorization policies.
has_all_permissions(*permissions)
¶
Return a guard that requires every configured permission.
Explicit-name alias of :func:has_permission that reads symmetrically next to
:func:has_any_permission; both apply identical conjunctive semantics.
Source code in litestar_auth/guards/_permission_guards.py
has_all_roles(*roles)
¶
Return a guard that requires all configured normalized roles.
The returned guard first enforces the same authenticated-active user contract as
:func:is_active, then compares the normalized flat role membership exposed by
the authenticated user against the configured roles. Both sides use the same
trim/lowercase/deduplicate/sort semantics as the model and manager layers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*roles
|
RoleNameT
|
Required role names. At least one role must be provided. Each value is normalized with trim/lowercase/deduplicate/sort semantics, and empty or whitespace-only role names are rejected at guard-build time. |
()
|
Returns:
| Type | Description |
|---|---|
Guard
|
Litestar-compatible guard callable for route |
Source code in litestar_auth/guards/_guards.py
has_any_permission(*permissions)
¶
Return a guard that requires at least one configured permission.
Source code in litestar_auth/guards/_permission_guards.py
has_any_role(*roles)
¶
Return a guard that requires any configured normalized role.
The returned guard first enforces the same authenticated-active user contract as
:func:is_active, then compares the normalized flat role membership exposed by
the authenticated user against the configured roles. Both sides use the same
trim/lowercase/deduplicate/sort semantics as the model and manager layers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
*roles
|
RoleNameT
|
Required role names. At least one role must be provided. Each value is normalized with trim/lowercase/deduplicate/sort semantics, and empty or whitespace-only role names are rejected at guard-build time. |
()
|
Returns:
| Type | Description |
|---|---|
Guard
|
Litestar-compatible guard callable for route |
Source code in litestar_auth/guards/_guards.py
has_any_scope(*scopes)
¶
Return a guard requiring an API key to have any configured scope.
Source code in litestar_auth/guards/_api_key_guards.py
has_organization_permission(*permissions)
¶
Return a guard that requires organization-scoped effective permissions.
Source code in litestar_auth/guards/_organization_guards.py
has_organization_role(*roles)
¶
Return a guard that requires organization-scoped membership roles.
Source code in litestar_auth/guards/_organization_guards.py
has_permission(*permissions)
¶
Return a guard that requires every configured permission.
Conjunctive permission check: the request is allowed only when the user's
effective permissions satisfy every argument. :func:has_all_permissions is
the explicit-name alias provided for symmetry with :func:has_any_permission.
Source code in litestar_auth/guards/_permission_guards.py
has_scope(*scopes)
¶
Return a guard requiring an API key to have every configured scope.
is_active(connection, _handler)
¶
Ensure the authenticated user is active.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection
|
ASGIConnection[Any, Any, Any, Any]
|
Incoming ASGI connection (Litestar request scope). |
required |
_handler
|
BaseRouteHandler
|
Route handler being guarded; unused but required by Litestar guard signature. |
required |
Note
Delegates to :func:_require_active_guarded_user for exceptions.
Source code in litestar_auth/guards/_guards.py
is_authenticated(connection, _handler)
¶
Ensure the request has an authenticated user.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection
|
ASGIConnection[Any, Any, Any, Any]
|
Incoming ASGI connection (Litestar request scope). |
required |
_handler
|
BaseRouteHandler
|
Route handler being guarded; unused but required by Litestar guard signature. |
required |
Raises:
| Type | Description |
|---|---|
NotAuthorizedException
|
Raised when no authenticated user is attached to the connection. |
Source code in litestar_auth/guards/_guards.py
is_superuser(connection, _handler)
¶
Ensure the authenticated user has superuser privileges.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection
|
ASGIConnection[Any, Any, Any, Any]
|
Incoming ASGI connection (Litestar request scope). |
required |
_handler
|
BaseRouteHandler
|
Route handler being guarded; unused but required by Litestar guard signature. |
required |
Raises:
| Type | Description |
|---|---|
PermissionDeniedException
|
Raised when the user lacks superuser privileges. |
Note
:func:_require_active_guarded_user may raise :exc:NotAuthorizedException when no user is
present, or :exc:PermissionDeniedException for missing account state or inactive users.
Source code in litestar_auth/guards/_guards.py
is_verified(connection, _handler)
¶
Ensure the authenticated user has a verified account.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
connection
|
ASGIConnection[Any, Any, Any, Any]
|
Incoming ASGI connection (Litestar request scope). |
required |
_handler
|
BaseRouteHandler
|
Route handler being guarded; unused but required by Litestar guard signature. |
required |
Raises:
| Type | Description |
|---|---|
PermissionDeniedException
|
Raised when the user is unverified. |
Note
:func:_require_active_guarded_user may raise :exc:NotAuthorizedException when no user is
present, or :exc:PermissionDeniedException for missing account state or inactive users.
Source code in litestar_auth/guards/_guards.py
requires_api_key(connection, _handler)
¶
Require authentication through the API-key backend.
Source code in litestar_auth/guards/_api_key_guards.py
requires_organization_membership(connection, _handler)
¶
Require the authenticated active user to have a verified current organization.
Source code in litestar_auth/guards/_organization_guards.py
requires_password_session(connection, _handler)
¶
Reject API-key-authenticated callers from password-session-only routes.