Database adapters¶
The litestar_auth.db package exposes only the abstract persistence contracts and their lightweight data payloads: BaseUserStore, BaseOAuthAccountStore, BaseApiKeyStore, BaseOrganizationStore, OAuthAccountData, ApiKeyData, OrganizationData, MembershipData, and OrganizationInvitationData. These protocols describe how the user manager and optional feature surfaces talk to your storage layer without tying the library to a particular ORM.
The concrete SQLAlchemy implementations live in a dedicated submodule: import SQLAlchemyUserDatabase, SQLAlchemyApiKeyStore, and SQLAlchemyOrganizationStore from litestar_auth.db.sqlalchemy. They are not re-exported from litestar_auth.db on purpose—eagerly importing the adapter would register SQLAlchemy mappers and break the lazy-import boundary described in the project guide. Use the submodule when you are ready to wire real tables.
For end-to-end ORM setup (session maker, models, plugin config), see User and manager, Backends, and Organizations; the Configuration index lists every split reference page. For customizing the user table while keeping OAuth accounts on the bundled model, see Custom user + OAuth.
from litestar_auth.db.sqlalchemy import SQLAlchemyUserDatabase
from litestar_auth.db.sqlalchemy import SQLAlchemyApiKeyStore
from litestar_auth.db.sqlalchemy import SQLAlchemyOrganizationStore
Organization persistence¶
Use BaseOrganizationStore[ORG, MEMBERSHIP, INVITATION, ID] for custom organization backends. The protocol
supports organization create/get/get-by-slug operations, exact membership add/get/list/remove
operations, atomic membership remove/role-update operations that preserve at least one privileged member,
listing organizations for a user, and email-scoped invitation create/get/list/revoke/consume
operations that store only a hashed token reference. Membership, user-organization, and pending-invitation list
methods are paginated store calls: they accept keyword-only offset and limit arguments and return
(items, total), where total is the count of the full filtered result set.
from litestar_auth.db import BaseOrganizationStore, MembershipData, OrganizationData, OrganizationInvitationData
Use SQLAlchemyOrganizationStore when the bundled SQLAlchemy adapter matches your model family:
from sqlalchemy.ext.asyncio import AsyncSession
from litestar_auth.db.sqlalchemy import SQLAlchemyOrganizationStore
from litestar_auth.models import Organization, OrganizationInvitation, OrganizationMembership
def create_store(session: AsyncSession) -> SQLAlchemyOrganizationStore:
return SQLAlchemyOrganizationStore(
session,
organization_model=Organization,
membership_model=OrganizationMembership,
invitation_model=OrganizationInvitation,
)
The adapter requires explicit organization_model and membership_model arguments. Invitation methods additionally
require invitation_model, and fail with TypeError when it is omitted. Organization
models remain lazy exports from litestar_auth.models; they are not exposed by litestar_auth.db.
litestar_auth.db
¶
Database abstractions and implementations.
ApiKeyData(key_id, user_id, hashed_secret, encrypted_secret, name, scopes, prefix_env, signing_required, expires_at, created_via, client_metadata=None)
dataclass
¶
Persistence fields required to create an API-key row.
BaseApiKeyStore
¶
Bases: Protocol
Structural CRUD contract for API-key persistence backends.
create(data)
async
¶
create_for_user_with_limit(data, *, max_keys_per_user)
async
¶
Persist an API key only when the user is still below the active-key limit.
delete_for_user(user_id)
async
¶
Permanently delete all API-key rows for user_id.
Returns:
| Type | Description |
|---|---|
int
|
Number of rows deleted when the backend can report it, otherwise |
get_by_key_id(key_id, *, include_inactive=False)
async
¶
list_for_user(user_id, *, include_inactive=False)
async
¶
list_signing_keys_requiring_reencrypt(requires_reencrypt, *, include_inactive=False)
async
¶
Return signing API-key rows whose encrypted secret needs keyring rotation.
replace_signing_key_encrypted_secret(key_id, *, encrypted_secret)
async
¶
Replace one signing API-key row's encrypted secret without changing other fields.
revoke(key_id, *, revoked_at)
async
¶
update(key_id, *, name=None, scopes=None)
async
¶
update_last_used_at(key_id, *, last_used_at)
async
¶
BaseOAuthAccountStore
¶
BaseOrganizationStore
¶
Bases: Protocol
Structural CRUD contract for organization persistence backends.
add_membership(data)
async
¶
consume_invitation(invitation_id, *, consumed_at)
async
¶
Atomically mark one pending invitation as consumed and return it when successful.
create_invitation(data)
async
¶
create_organization(data)
async
¶
delete_organization(organization_id)
async
¶
get_invitation(invitation_id)
async
¶
get_invitation_by_token_hash(token_hash)
async
¶
get_membership(*, organization_id, user_id)
async
¶
get_organization(organization_id)
async
¶
get_organization_by_slug(slug)
async
¶
list_memberships(organization_id, *, offset, limit)
async
¶
Return paginated memberships for one organization and the total available count.
list_organizations_for_user(user_id, *, offset, limit)
async
¶
Return paginated organizations for user_id and the total available count.
list_pending_invitations(organization_id, *, now, offset, limit)
async
¶
Return paginated unexpired pending invitations and the total available count.
remove_membership(*, organization_id, user_id)
async
¶
remove_membership_preserving_privileged_member(*, organization_id, user_id, privileged_roles)
async
¶
Atomically remove a membership without removing the final privileged member.
Raises:
| Type | Description |
|---|---|
ValueError
|
If removing the row would leave the organization without a privileged member. |
Source code in litestar_auth/db/base.py
revoke_invitation(invitation_id)
async
¶
set_membership_roles(*, organization_id, user_id, roles)
async
¶
Replace roles on an existing organization membership and return the updated row.
set_membership_roles_preserving_privileged_member(*, organization_id, user_id, roles, privileged_roles)
async
¶
Atomically replace roles without demoting the final privileged member.
Raises:
| Type | Description |
|---|---|
ValueError
|
If replacing roles would leave the organization without a privileged member. |
Source code in litestar_auth/db/base.py
update_organization(organization_id, data)
async
¶
Persist mutable organization fields and return the updated row when present.
BaseUserStore
¶
Bases: Protocol
Structural CRUD interface for user persistence backends.
create(user_dict)
async
¶
delete(user_id)
async
¶
get(user_id)
async
¶
get_by_email(email)
async
¶
get_by_field(field_name, value)
async
¶
Return the user where field_name equals value, if present.
field_name must be "email" or "username" (see
:data:~litestar_auth.types.LoginIdentifier). Implementations may perform a
direct column/attribute lookup. Values outside that set are a
programming error and may surface as backend-specific errors at
runtime when callers bypass static typing.
Source code in litestar_auth/db/base.py
list_users(*, offset, limit)
async
¶
MembershipData(organization_id, user_id, roles)
dataclass
¶
Persistence fields required to create an organization membership row.
OAuthAccountData(oauth_name, account_id, account_email, access_token, expires_at, refresh_token)
dataclass
¶
Provider account identity and token fields for OAuth-account persistence.
OrganizationData(slug, name)
dataclass
¶
Persistence fields required to create an organization row.
OrganizationInvitationData(organization_id, invited_email, roles, token_hash, expires_at)
dataclass
¶
Persistence fields required to create an organization invitation row.