Registration, verification, and password reset¶
Enable or disable slices of the auth HTTP API with flags on LitestarAuthConfig.
The built-in lifecycle controllers do not use one generic credential field. identifier belongs to login
(LoginCredentials) only. Registration, email verification, password reset, and the built-in TOTP flow keep their
current email/token-oriented request contracts unless you replace the relevant controller. The public API reference for
those built-in request and response structs now lives on the Payloads and schemas API page.
Registration¶
With include_register=True (default), clients can call POST {auth_path}/register.
- Built-in request body —
UserCreatepublishesemailandpasswordin OpenAPI. - Login identifier —
login_identifieris"email"or"username"and selects howPOST .../loginresolvesLoginCredentials.identifier. It does not rename the built-in registration fields. - Safe creation — registration uses
BaseUserManager.create(..., safe=True)so only expected fields (e.g. email + password) are accepted; privileged fields such asroles,is_active, andis_verifiedare stripped from public registration payloads unless you explicitly opt into privileged manager calls. The built-inUserCreaterequest schema is strict, and customuser_create_schemavalues passed tocreate_register_controller(...)must also setforbid_unknown_fields=True, so stale request keys fail withREQUEST_BODY_INVALIDinstead of being silently ignored. Grant superuser access by assigning the configured superuser role instead. - Built-in response body — successful register/verify/reset responses use
UserRead, which includes normalizedrolesalongside the existing account-state fields. New users start withroles=[]unless a privileged path assigns them. - Failure surface — registration is enumeration-resistant. Duplicate identifiers, password-policy failures,
and manager authorization rejections all return the same 400 /
REGISTER_FAILEDresponse with the generic detailRegistration could not be completed.Specific Python exceptions remain available inside the manager/controller boundary for operator diagnostics. When a duplicate identifier is detected, the manager also invokeson_after_register_duplicate(user)with the existing account so you can enqueue an out-of-band owner notification without changing the public response. - Timing envelope — plugin-owned registration responses are also padded to
LitestarAuthConfig.register_minimum_response_seconds(default0.4) on both success and domain-failure paths. The minimum-duration wait is a lower-tail timing-oracle defense and does not replace rate limiting. Keep duplicate-register notification work in a background queue; slow synchronous I/O inon_after_register_duplicatecan still make duplicate attempts observably slower. - Persistence boundary — relational
role/user_roletables are an internal storage detail of the ORM layer. Registration still accepts flat user fields only, and this route surface does not expose role-catalog management or RBAC policy payloads. Use the opt-in HTTP role administration guide or the operator CLI when you need admin workflows.
Email verification¶
With include_verify=True:
POST .../request-verify-token—RequestVerifyTokenwithemail; issues a new verification token when the email belongs to an existing unverified user, while keeping the public response and manager hook contract enumeration-resistant.POST .../verify—VerifyTokenwithtoken; consumes a verification token.
LitestarAuthConfig.requires_verification now defaults to True, so newly registered accounts must
verify their email before /login or built-in /2fa/verify can complete unless you opt out
explicitly.
The library does not send email. Implement on_after_request_verify_token and related hooks on
your user manager to enqueue mail or notifications, and make sure the hook performs equivalent async
work even when it receives user=None / token=None for unknown or already-verified emails.
Password reset¶
With include_reset_password=True:
POST .../forgot-password—ForgotPasswordwithemail; returns 202 Accepted with the same shape whether the email exists (enumeration-safe). When rate limits apply, the counter increments after handler completion without exposing whether the user existed.POST .../reset-password—ResetPasswordwithtoken+password.
Reset tokens are tied to a password fingerprint so they invalidate after a successful password change. Implement on_after_forgot_password to send the link out-of-band.
TOTP boundary¶
login_identifier="username" does not make the built-in 2FA flow username-based. TOTP enrollment and default password step-up still use user.email, and the enrollment response still returns an email-based otpauth URI.
User schema helpers¶
The password-wiring contract now lives in
Configuration. For custom registration
DTOs, reuse litestar_auth.schemas.UserEmailField and litestar_auth.schemas.UserPasswordField
when you want the built-in email/password metadata without copying local constraints. Existing
UserPasswordField imports remain valid; add UserEmailField only when you also want the
built-in email contract. Those aliases only affect schema validation and OpenAPI. Runtime password
policy still comes from password_validator_factory or the manager's default
require_password_length validator.
When you keep the built-in register/verify/reset/users controllers but replace user_read_schema
or user_update_schema, keep the default role-aware contract in mind: built-in UserRead
includes roles, built-in AdminUserUpdate accepts optional roles, and the self-service
UserUpdate is limited to email plus current_password proof for email changes — privileged
fields (is_active, is_verified, roles) are rejected at msgspec decode on /users/me so the
persistence layer never sees a self-service body that tries to escalate. Admin PATCH /users/{id}
continues to persist those fields through AdminUserUpdate. Outside the built-in controllers, direct
BaseUserManager.update(...) calls must pass allow_privileged=True before mutating
is_active, is_verified, or roles.
Related¶
- Backends —
include_register,include_verify,include_reset_password,login_identifier. - Extending — hooks on
BaseUserManager. - Payloads and schemas API — built-in auth lifecycle DTOs from
litestar_auth.payloadsplus the default user CRUD schemas fromlitestar_auth.schemas.