application tier

application-auth

Forge module wrapping identity-auth. Sprint 65: owns the staff + customer auth subsystem (repo/auth, customer_auth/workflows services, admin_auth + api_admin_auth middleware, JSON auth routers) extracted from rust-cms-engine.

Forge module wrapping identity-auth. Sprint 65: owns the staff + customer auth subsystem (repo/auth, customer_auth/workflows services, admin_auth + api_admin_auth middleware, JSON auth routers) extracted from rust-cms-engine.

Tierapplication
Roleunclassified (baselined)
Pathcrates/application/auth
Edition2024
Targetsapplication_auth, me_email, pg_forge_auth_migrations
Public items106 across 20 modules
Tests34

What it is for

application-auth — wraps identity-auth.

Sprint 65: also owns the staff + customer authentication subsystem lifted from rust-cms-engine — account persistence (repo::auth), the customer auth + workflow services (services), the structural /admin + /api/admin middleware (middleware), and the JSON auth routers (api).

Capabilities

crate root

application-auth — wraps identity-auth.

Item
async fn seed_admin_user(pool : & PgPool, email : & str, password : & str,) -> Result <bool, sqlx::Error>

AuthModule

application-auth — wraps identity-auth.

Item
pub struct AuthModule
AuthModule :: fn new() -> Self
AuthModule :: fn name(& self) -> & 'static str
AuthModule :: fn version(& self) -> & 'static str
AuthModule :: fn migrations(& self) -> Vec <MigrationSet>
AuthModule :: async fn migrate_pending(& self, pool : & PgPool) -> std::result::Result <u32, MigrationError>
AuthModule :: fn public_router(& self) -> axum::Router <S>

api (other)

Auth JSON routers (Sprint 65: extracted from rust-cms-engine).

Item
fn api_keys_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,
fn router_v1 <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

api::admin_console (other)

Sprint 65: extracted from rust-cms-engine.

Item
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,
fn me_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, identity_user_prefs::LocaleSettings : FromRef <S>,

api::api_keys (other)

Self-service API-key management (Sprint 0.67).

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

api::auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,
fn router_v1 <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

MeResponse

Sprint 65: extracted from rust-cms-engine.

Item
pub struct MeResponse

PermissionsResponse

Sprint 65: extracted from rust-cms-engine.

Item
pub struct PermissionsResponse

api::customer_auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

api::customer_workflows (other)

Sprint 65: extracted from rust-cms-engine.

Item
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,

middleware::api_admin_auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
async fn api_admin_auth(State(pool) : State <PgPool>, session : Session, ConnectInfo(peer) : ConnectInfo <SocketAddr>, mut req : Request, next : Next,) -> Response

middleware::auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
pub const SESSION_USER_ID_KEY: & str
pub const SESSION_ACTIVE_TENANT_KEY: & str
pub const FORCE_PASSWORD_PATH: & str
async fn admin_auth(State(pool) : State <PgPool>, session : Session, ConnectInfo(peer) : ConnectInfo <SocketAddr>, mut req : Request, next : Next,) -> Response

repo::api_keys (other)

API-key persistence + verification lookup (Sprint 0.67).

Item
async fn create(pool : & PgPool, tenant_id : Uuid, owner_id : Uuid, created_by : Uuid, name : & str, scopes : & String, expires_at : Option <DateTime <Utc>>,) -> Result <(Uuid, String), sqlx::Error>
async fn revoke(pool : & PgPool, id : Uuid, owner_id : Uuid) -> Result <bool, sqlx::Error>
async fn touch_last_used(pool : & PgPool, id : Uuid) -> Result <(), sqlx::Error>

ApiKeyRow

API-key persistence + verification lookup (Sprint 0.67).

Item
pub struct ApiKeyRow
async fn list_for_owner(pool : & PgPool, owner_id : Uuid, tenant_id : Uuid,) -> Result <Vec <ApiKeyRow>, sqlx::Error>
ApiKeyRow :: fn from(r : ApiKeyRowSql) -> Self

VerifiedKey

API-key persistence + verification lookup (Sprint 0.67).

Item
pub struct VerifiedKey
async fn verify_key(pool : & PgPool, plaintext : & str,) -> Result <Option <VerifiedKey>, sqlx::Error>

repo::auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
fn status_str(status : UserStatus) -> & 'static str
async fn touch_last_login(pool : & PgPool, id : Uuid) -> Result <(), sqlx::Error>
async fn set_password <'e, E>(executor : E, id : Uuid, new_hash : & str, must_change_password : bool,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,
async fn update_display_name <'e, E>(executor : E, id : Uuid, display_name : & str,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,
async fn update_status <'e, E>(executor : E, id : Uuid, status : UserStatus,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,

Account

Sprint 65: extracted from rust-cms-engine.

Item
pub struct Account
async fn find_account_by_email(pool : & PgPool, email : & str,) -> Result <Option <Account>, sqlx::Error>
async fn find_account_by_id(pool : & PgPool, id : Uuid) -> Result <Option <Account>, sqlx::Error>
async fn count_accounts(pool : & PgPool) -> Result <i64, sqlx::Error>
async fn create_account <'e, E>(executor : E, user : & User, display_name : & str, must_change_password : bool,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,
async fn list_accounts(pool : & PgPool) -> Result <Vec <AccountListRow>, sqlx::Error>

AccountListRow

Sprint 65: extracted from rust-cms-engine.

Item
pub struct AccountListRow

repo::login_attempts (other)

Login-attempt persistence + recent-failure counts (Sprint 0.66 T2).

Item
async fn record_attempt(pool : & PgPool, attempt : & LoginAttempt) -> Result <(), sqlx::Error>
async fn recent_failure_counts(pool : & PgPool, ip_address : & str, email : & str, policy : & LockoutPolicy,) -> Result <FailureCounts, sqlx::Error>

services::admin_screens (other)

Sprint 65: extracted from rust-cms-engine.

Item
async fn list_audit(pool : & PgPool, filter : AuditFilter, limit : i64,) -> Result <Vec <AuditRow>, AdminError>
async fn list_contact(pool : & PgPool, filter : ContactFilter, limit : i64,) -> Result <Vec <ContactSubmission>, AdminError>
async fn contact_detail(pool : & PgPool, id : Uuid) -> Result <Option <ContactDetail>, AdminError>
async fn add_contact_note(pool : & PgPool, submission_id : Uuid, author_id : Uuid, body : String,) -> Result <ContactNote, AdminError>
async fn list_users(pool : & PgPool, limit : i64) -> Result <Vec <UserRow>, AdminError>
async fn invite_user(pool : & PgPool, input : InviteUserInput, actor_id : Uuid,) -> Result <InviteResult, AdminError>
async fn list_roles(pool : & PgPool) -> Result <Vec <RoleRow>, AdminError>
async fn list_permissions(pool : & PgPool) -> Result <Vec <PermissionRow>, AdminError>
async fn get_profile(pool : & PgPool, user_id : Uuid) -> Result <ProfileResponse, AdminError>
async fn update_profile(pool : & PgPool, user_id : Uuid, patch : UpdateProfileInput,) -> Result <ProfileResponse, AdminError>
async fn change_email(pool : & PgPool, user_id : Uuid, input : UpdateEmailInput, require_verification : bool,) -> Result <ProfileResponse, AdminError>
async fn change_password(pool : & PgPool, user_id : Uuid, input : ChangePasswordInput,) -> Result <(), AdminError>

AdminError

Sprint 65: extracted from rust-cms-engine.

Item
pub enum AdminError
async fn mark_contact_read(pool : & PgPool, id : Uuid, actor_id : Uuid) -> Result <(), AdminError>
async fn get_settings(pool : & PgPool) -> Result <serde_json::Value, AdminError>
async fn update_settings(pool : & PgPool, patch : serde_json::Value, actor_id : Uuid,) -> Result <serde_json::Value, AdminError>
async fn email_verification_required(pool : & PgPool) -> Result <bool, AdminError>

AuditFilter

Sprint 65: extracted from rust-cms-engine.

Item
pub struct AuditFilter

AuditRow

Sprint 65: extracted from rust-cms-engine.

Item
pub struct AuditRow

ChangePasswordInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ChangePasswordInput

ContactDetail

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ContactDetail

ContactFilter

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ContactFilter

ContactNote

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ContactNote

ContactSubmission

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ContactSubmission

InviteResult

Sprint 65: extracted from rust-cms-engine.

Item
pub struct InviteResult

InviteUserInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct InviteUserInput

PermissionRow

Sprint 65: extracted from rust-cms-engine.

Item
pub struct PermissionRow

ProfileResponse

Sprint 65: extracted from rust-cms-engine.

Item
pub struct ProfileResponse

RoleRow

Sprint 65: extracted from rust-cms-engine.

Item
pub struct RoleRow

UpdateEmailInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct UpdateEmailInput

UpdateProfileInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct UpdateProfileInput

UserRow

Sprint 65: extracted from rust-cms-engine.

Item
pub struct UserRow

ApiKeyPrincipal

API-key request authentication — resolve a presented sk_ key to a

Item
pub struct ApiKeyPrincipal
async fn authenticate(pool : & PgPool, plaintext : & str,) -> Result <Option <ApiKeyPrincipal>, sqlx::Error>

services::api_key_scope (other)

API-key scope + principal logic (Sprint 0.67, Gate 1.5 D2).

Item
fn parse_bearer(header_value : & str) -> Option <& str>
fn effective_permissions(owner_perms : & HashSet <String>, key_scopes : & String,) -> HashSet <String>

ScopeMintError

API-key scope + principal logic (Sprint 0.67, Gate 1.5 D2).

Item
pub enum ScopeMintError
fn scopes_mintable_by(creator_perms : & HashSet <String>, requested_scopes : & String, known_perms : & HashSet <String>,) -> Result <(), ScopeMintError>

services::customer_auth (other)

Sprint 65: extracted from rust-cms-engine.

Item
async fn signup(pool : & PgPool, input : SignupInput) -> Result <(), CustomerAuthError>
async fn login(pool : & PgPool, session : & Session, input : LoginInput, client_ip : Option <& str>, user_agent : Option <& str>,) -> Result <MeResponse, CustomerAuthError>
async fn me(pool : & PgPool, user_id : Uuid) -> Result <Option <MeResponse>, CustomerAuthError>

CustomerAuthError

Sprint 65: extracted from rust-cms-engine.

Item
pub enum CustomerAuthError
async fn logout(session : & Session) -> Result <(), CustomerAuthError>

LoginInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct LoginInput

MeResponse

Sprint 65: extracted from rust-cms-engine.

Item
pub struct MeResponse

SignupInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct SignupInput

services::customer_workflows (other)

Sprint 65: extracted from rust-cms-engine.

Item
async fn submit_inquiry(pool : & PgPool, input : InquiryInput, user_id : Option <Uuid>, ip : Option <& str>, user_agent : Option <& str>,) -> Result <Uuid, CustomerError>

CustomerError

Sprint 65: extracted from rust-cms-engine.

Item
pub enum CustomerError
async fn enqueue_email(pool : & PgPool, template_key : & str, recipient_email : & str, context : serde_json::Value, idempotency_key : Option <& str>,) -> Result <Uuid, CustomerError>
async fn issue_verification_token(pool : & PgPool, user_id : Uuid,) -> Result <String, CustomerError>
async fn verify_email_token(pool : & PgPool, raw_token : & str) -> Result <Uuid, CustomerError>
async fn issue_password_reset_token(pool : & PgPool, email : & str,) -> Result <Option <String>, CustomerError>
async fn consume_password_reset(pool : & PgPool, raw_token : & str, new_password : & str,) -> Result <Uuid, CustomerError>
async fn delete_account(pool : & PgPool, user_id : Uuid) -> Result <(), CustomerError>

InquiryInput

Sprint 65: extracted from rust-cms-engine.

Item
pub struct InquiryInput

FailureCounts

Brute-force lockout policy (Sprint 0.66 T2).

Item
pub struct FailureCounts

LockoutDecision

Brute-force lockout policy (Sprint 0.66 T2).

Item
pub enum LockoutDecision

LockoutPolicy

Brute-force lockout policy (Sprint 0.66 T2).

Item
pub struct LockoutPolicy
LockoutPolicy :: fn default() -> Self
LockoutPolicy :: fn evaluate(& self, counts : FailureCounts) -> LockoutDecision

How to use it

No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.

Module structure

application_auth

flowchart TD
  n_application_auth["application_auth"]
  n_application_auth --> n_api["api"]
  n_api --> n_api__admin_console["admin_console"]
  n_api --> n_api__api_keys["api_keys"]
  n_api --> n_api__auth["auth"]
  n_api --> n_api__customer_auth["customer_auth"]
  n_api --> n_api__customer_workflows["customer_workflows"]
  n_application_auth --> n_middleware["middleware"]
  n_middleware --> n_middleware__api_admin_auth["api_admin_auth"]
  n_middleware --> n_middleware__auth["auth"]
  n_application_auth --> n_repo["repo"]
  n_repo --> n_repo__api_keys["api_keys"]
  n_repo --> n_repo__auth["auth"]
  n_repo --> n_repo__login_attempts["login_attempts"]
  n_application_auth --> n_services["services"]
  n_services --> n_services__admin_screens["admin_screens"]
  n_services --> n_services__api_key_auth["api_key_auth"]
  n_services --> n_services__api_key_scope["api_key_scope"]
  n_services --> n_services__customer_auth["customer_auth"]
  n_services --> n_services__customer_workflows["customer_workflows"]
  n_services --> n_services__lockout["lockout"]

Public surface

`crate root`

ItemWhat it is
async fn seed_admin_user(pool : & PgPool, email : & str, password : & str,) -> Result <bool, sqlx::Error>Seed an admin user (Sprint 65: lifted from the deleted CmsEngine::seed_admin_user)
pub struct AuthModule
AuthModule :: fn new() -> Self
AuthModule :: fn name(& self) -> & 'static str
AuthModule :: fn version(& self) -> & 'static str
AuthModule :: fn migrations(& self) -> Vec <MigrationSet>
AuthModule :: async fn migrate_pending(& self, pool : & PgPool) -> std::result::Result <u32, MigrationError>
AuthModule :: fn public_router(& self) -> axum::Router <S>Auth surfaces use legacy absolute paths (/api/v1/auth/*, /api/v1/keys), encapsulated here as the module's public router; the engine merges at root

`api`

ItemWhat it is
fn api_keys_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Self-service API-key management router (/api/v1/keys, session-gated).
fn router_v1 <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Canonical /api/v1/auth/* surface — the staff/customer JSON auth endpoints (login/logout/me/me-permissions).

`api::admin_console`

ItemWhat it is
fn admin_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Admin-half router
fn me_router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>, identity_user_prefs::LocaleSettings : FromRef <S>,Profile router

`api::api_keys`

ItemWhat it is
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Build the session-gated key-management router.

`api::auth`

ItemWhat it is
pub struct MeResponse
pub struct PermissionsResponse
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Build the JSON auth router (LEGACY shape per Sprint 10B 30-day deprecation alias — D-10B.3)
fn router_v1 <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Sprint 10B canonical auth surface — routes at /api/v1/auth/*

`api::customer_auth`

ItemWhat it is
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Customer-side router

`api::customer_workflows`

ItemWhat it is
fn router <S>() -> Router <S> where S : Clone + Send + Sync + 'static, PgPool : FromRef <S>,Public customer workflows router

`middleware::api_admin_auth`

ItemWhat it is
async fn api_admin_auth(State(pool) : State <PgPool>, session : Session, ConnectInfo(peer) : ConnectInfo <SocketAddr>, mut req : Request, next : Next,) -> ResponseGlobal middleware that self-scopes to the staff-API + per-user surfaces on both the legacy un-versioned and the canonical /api/v1/* paths

`middleware::auth`

ItemWhat it is
pub const SESSION_USER_ID_KEY: & strSession key holding the logged-in user's id (set at login).
pub const SESSION_ACTIVE_TENANT_KEY: & strSession key holding the user's active tenant selection (Sprint 0.55 model D).
pub const FORCE_PASSWORD_PATH: & strThe first-login forced password-change route — exempt from the must_change_password redirect so the user can actually reach it.
async fn admin_auth(State(pool) : State <PgPool>, session : Session, ConnectInfo(peer) : ConnectInfo <SocketAddr>, mut req : Request, next : Next,) -> ResponseGlobal middleware layer that self-scopes to the /admin surface.

`repo::api_keys`

ItemWhat it is
pub struct ApiKeyRowA persisted API-key row (read shape)
pub struct VerifiedKeyWhat a successful verification yields — the inputs the principal resolver needs (owner + bound tenant + granted scopes).
async fn create(pool : & PgPool, tenant_id : Uuid, owner_id : Uuid, created_by : Uuid, name : & str, scopes : & String, expires_at : Option <DateTime <Utc>>,) -> Result <(Uuid, String), sqlx::Error>Create a key for owner_id in tenant_id
async fn list_for_owner(pool : & PgPool, owner_id : Uuid, tenant_id : Uuid,) -> Result <Vec <ApiKeyRow>, sqlx::Error>List a user's keys within one tenant, newest first
async fn revoke(pool : & PgPool, id : Uuid, owner_id : Uuid) -> Result <bool, sqlx::Error>Revoke a key (only the owner's own)
async fn verify_key(pool : & PgPool, plaintext : & str,) -> Result <Option <VerifiedKey>, sqlx::Error>Verify a presented plaintext key: O(1) lookup by deterministic SHA-256 hash, requiring the key be active, not revoked, and not expired
async fn touch_last_used(pool : & PgPool, id : Uuid) -> Result <(), sqlx::Error>Throttled last_used_at bump — writes only if the stored value is NULL or older than 5 minutes, so a read-heavy key doesn't turn every call into a write (Gate 1.5)
ApiKeyRow :: fn from(r : ApiKeyRowSql) -> Self

`repo::auth`

ItemWhat it is
pub struct AccountA persisted account — the library crates User plus the app-local display_name and must_change_password columns.
fn status_str(status : UserStatus) -> & 'static strThe DB string for a UserStatus (users.status is VARCHAR).
async fn find_account_by_email(pool : & PgPool, email : & str,) -> Result <Option <Account>, sqlx::Error>Look up an account by email (case-insensitive), live rows only.
async fn find_account_by_id(pool : & PgPool, id : Uuid) -> Result <Option <Account>, sqlx::Error>Look up an account by id, live rows only.
async fn count_accounts(pool : & PgPool) -> Result <i64, sqlx::Error>Count live accounts — used by the first-boot seed.
async fn touch_last_login(pool : & PgPool, id : Uuid) -> Result <(), sqlx::Error>Stamp last_login_at = NOW().
async fn create_account <'e, E>(executor : E, user : & User, display_name : & str, must_change_password : bool,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,Insert a new account
async fn set_password <'e, E>(executor : E, id : Uuid, new_hash : & str, must_change_password : bool,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,Replace an account's password hash and set its must_change_password flag (an admin reset sets it true; a self-service change clears it).
async fn update_display_name <'e, E>(executor : E, id : Uuid, display_name : & str,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,Update an account's display name.
async fn update_status <'e, E>(executor : E, id : Uuid, status : UserStatus,) -> Result <(), sqlx::Error> where E : Executor <'e, Database = Postgres>,Set an account's status (deactivate / reactivate).
pub struct AccountListRowA row of the account list (/admin/settings → Accounts) — joined to the account's current role
async fn list_accounts(pool : & PgPool) -> Result <Vec <AccountListRow>, sqlx::Error>Every live account with its current role — active first, then by descending role level (deactivated accounts sink to the bottom).

`repo::login_attempts`

ItemWhat it is
async fn record_attempt(pool : & PgPool, attempt : & LoginAttempt) -> Result <(), sqlx::Error>Append a login attempt (success or failure) to login_attempts
async fn recent_failure_counts(pool : & PgPool, ip_address : & str, email : & str, policy : & LockoutPolicy,) -> Result <FailureCounts, sqlx::Error>Count recent FAILED attempts for each layered key, each over its own window

`services::admin_screens`

ItemWhat it is
pub enum AdminError
pub struct AuditRow
pub struct AuditFilter
async fn list_audit(pool : & PgPool, filter : AuditFilter, limit : i64,) -> Result <Vec <AuditRow>, AdminError>
pub struct ContactSubmission
pub struct ContactFilter
async fn list_contact(pool : & PgPool, filter : ContactFilter, limit : i64,) -> Result <Vec <ContactSubmission>, AdminError>
pub struct ContactNote
pub struct ContactDetail
async fn contact_detail(pool : & PgPool, id : Uuid) -> Result <Option <ContactDetail>, AdminError>Per Sprint 10A US-10A.4: full submission + notes thread.
async fn add_contact_note(pool : & PgPool, submission_id : Uuid, author_id : Uuid, body : String,) -> Result <ContactNote, AdminError>Per Sprint 10A US-10A.4: add a staff note to a submission.
async fn mark_contact_read(pool : & PgPool, id : Uuid, actor_id : Uuid) -> Result <(), AdminError>
async fn get_settings(pool : & PgPool) -> Result <serde_json::Value, AdminError>Return all site_settings columns as a flat JSON object
async fn update_settings(pool : & PgPool, patch : serde_json::Value, actor_id : Uuid,) -> Result <serde_json::Value, AdminError>Apply a partial update by treating the patch JSON object as a column → value map
async fn email_verification_required(pool : & PgPool) -> Result <bool, AdminError>Read the require_email_verification site setting (Sprint 0.99 Phase 1.1)
pub struct UserRow
async fn list_users(pool : & PgPool, limit : i64) -> Result <Vec <UserRow>, AdminError>
pub struct InviteUserInput
pub struct InviteResultSprint 5 simpler invite: create the user with a random password, assign the role, return the temp password to the operator
async fn invite_user(pool : & PgPool, input : InviteUserInput, actor_id : Uuid,) -> Result <InviteResult, AdminError>
pub struct RoleRow
async fn list_roles(pool : & PgPool) -> Result <Vec <RoleRow>, AdminError>
pub struct PermissionRow
async fn list_permissions(pool : & PgPool) -> Result <Vec <PermissionRow>, AdminError>
pub struct ProfileResponse
async fn get_profile(pool : & PgPool, user_id : Uuid) -> Result <ProfileResponse, AdminError>
pub struct UpdateProfileInput
async fn update_profile(pool : & PgPool, user_id : Uuid, patch : UpdateProfileInput,) -> Result <ProfileResponse, AdminError>
pub struct ChangePasswordInput
pub struct UpdateEmailInputBody for PATCH /me/email
async fn change_email(pool : & PgPool, user_id : Uuid, input : UpdateEmailInput, require_verification : bool,) -> Result <ProfileResponse, AdminError>Change the session user's login email
async fn change_password(pool : & PgPool, user_id : Uuid, input : ChangePasswordInput,) -> Result <(), AdminError>

`services::api_key_auth`

ItemWhat it is
pub struct ApiKeyPrincipalA resolved API-key principal
async fn authenticate(pool : & PgPool, plaintext : & str,) -> Result <Option <ApiKeyPrincipal>, sqlx::Error>Authenticate a presented plaintext key

`services::api_key_scope`

ItemWhat it is
fn parse_bearer(header_value : & str) -> Option <& str>Extract the sk_-prefixed token from an Authorization header value
fn effective_permissions(owner_perms : & HashSet <String>, key_scopes : & String,) -> HashSet <String>Least-privilege intersection: the permissions a key request actually carries
pub enum ScopeMintErrorWhy a requested scope set cannot be minted.
fn scopes_mintable_by(creator_perms : & HashSet <String>, requested_scopes : & String, known_perms : & HashSet <String>,) -> Result <(), ScopeMintError>Creation guard: a key may only be granted scopes that are (a) real permission codenames and (b) already held by the creator

`services::customer_auth`

ItemWhat it is
pub enum CustomerAuthError
pub struct SignupInput
pub struct LoginInput
pub struct MeResponse
async fn signup(pool : & PgPool, input : SignupInput) -> Result <(), CustomerAuthError>Signup
async fn login(pool : & PgPool, session : & Session, input : LoginInput, client_ip : Option <& str>, user_agent : Option <& str>,) -> Result <MeResponse, CustomerAuthError>Login
async fn logout(session : & Session) -> Result <(), CustomerAuthError>Logout
async fn me(pool : & PgPool, user_id : Uuid) -> Result <Option <MeResponse>, CustomerAuthError>Read the current customer's profile

`services::customer_workflows`

ItemWhat it is
pub enum CustomerError
async fn enqueue_email(pool : & PgPool, template_key : & str, recipient_email : & str, context : serde_json::Value, idempotency_key : Option <& str>,) -> Result <Uuid, CustomerError>
async fn issue_verification_token(pool : & PgPool, user_id : Uuid,) -> Result <String, CustomerError>
async fn verify_email_token(pool : & PgPool, raw_token : & str) -> Result <Uuid, CustomerError>
async fn issue_password_reset_token(pool : & PgPool, email : & str,) -> Result <Option <String>, CustomerError>
async fn consume_password_reset(pool : & PgPool, raw_token : & str, new_password : & str,) -> Result <Uuid, CustomerError>
pub struct InquiryInput
async fn submit_inquiry(pool : & PgPool, input : InquiryInput, user_id : Option <Uuid>, ip : Option <& str>, user_agent : Option <& str>,) -> Result <Uuid, CustomerError>
async fn delete_account(pool : & PgPool, user_id : Uuid) -> Result <(), CustomerError>

`services::lockout`

ItemWhat it is
pub struct LockoutPolicyThresholds + sliding windows for the layered brute-force guard
LockoutPolicy :: fn default() -> Self
pub struct FailureCountsRecent FAILED-attempt counts, each already counted over its own window by the repo layer
pub enum LockoutDecisionThe guard's verdict for an incoming login attempt.
LockoutPolicy :: fn evaluate(& self, counts : FailureCounts) -> LockoutDecisionPure decision: Locked if ANY layered threshold is met or exceeded, else Allow

Re-exports. Exported here, defined elsewhere.

ExportDefined in
Accountrepo::auth::Account
api_admin_authmiddleware::api_admin_auth::api_admin_auth
{FORCE_PASSWORD_PATH,SESSION_USER_ID_KEY,admin_auth}middleware::auth::{FORCE_PASSWORD_PATH,SESSION_USER_ID_KEY,admin_auth}
{admin_router,me_router}admin_console::{admin_router,me_router}

Boundary

Reaches into identity, platform.

Shares tier application with 120 other crates: application-agreements, application-ai, application-analytics, application-approvals, application-assessments, application-audit-log, application-billing, application-browser-automation, … (120 total).

_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._

Where it sits

Tier (ontology)application
Architectural role (taxonomy)unclassified (baselined)
Locationcrates/application/auth
Vocabulary in force (lexicon)current

Tier flow. Which tiers this crate's own edges cross.

flowchart LR
  n_application["application"] --> n_identity["identity"]
  n_application["application"] --> n_platform["platform"]

Dependencies

Runtime, in this workspace.

CrateTierOptionalOnly on
`application-audit-log`applicationnoalways
`application-core`applicationnoalways
`application-rbac`applicationnoalways
`identity-auth`identitynoalways
`identity-tenant`identitynoalways
`identity-user-prefs`identitynoalways
`platform-dto`platformnoalways

Runtime, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
async-trait^0.1noalways
axum^0.7multipartnoalways
chrono^0.4serdenoalways
hex^0.4noalways
rand^0.8noalways
serde^1derivenoalways
serde_json^1noalways
sha2^0.10noalways
sqlx^0.8runtime-tokio, postgres, chrono, uuid, jsonnoalways
thiserror^2noalways
tokio^1fullnoalways
tower-sessions^0.13noalways
tracing^0.1noalways
uuid^1v4, v7, serde, jsnoalways

Development, in this workspace.

CrateTierOptionalOnly on
`application-engine`applicationnoalways
`application-parties`applicationnoalways

Development, from outside the workspace.

CrateRequirementFeaturesOptionalOnly on
dotenvy^0.15noalways

Build. None.

Depended on by. 4 workspace crates.

Signal flow — what reaches this crate, and what it reaches.

flowchart LR
  n_application_agreements["application-agreements"] -->|uses| SELF
  n_application_catalog["application-catalog"] -->|uses| SELF
  n_application_cli["application-cli"] -->|uses| SELF
  n_application_cms["application-cms"] -->|uses| SELF
  SELF["application-auth"]
  SELF -->|development| n_application_engine["application-engine"]
  SELF -->|development| n_application_parties["application-parties"]
  SELF -->|runtime| n_application_audit_log["application-audit-log"]
  SELF -->|runtime| n_application_core["application-core"]
  SELF -->|runtime| n_application_rbac["application-rbac"]
  SELF -->|runtime| n_identity_auth["identity-auth"]
  SELF -->|runtime| n_identity_tenant["identity-tenant"]
  SELF -->|runtime| n_identity_user_prefs["identity-user-prefs"]
  SELF -->|runtime| n_platform_dto["platform-dto"]
  classDef self fill:#1f883d,stroke:#1f883d,color:#fff;
  class SELF self;

Feature flags

FeatureEnablesOn by default
postgresno
flowchart LR
  n_postgres["postgres"]

Targets

KindNameSource
libapplication_auth`src/lib.rs`
testme_email`tests/me_email.rs`
testpg_forge_auth_migrations`tests/pg_forge_auth_migrations.rs`

Error model

Error typeNamed by
AdminErroradd_contact_note, change_email, change_password, contact_detail, email_verification_required, get_profile, … (16 total)
CustomerAuthErrorlogin, logout, me, signup
CustomerErrorconsume_password_reset, delete_account, enqueue_email, issue_password_reset_token, issue_verification_token, submit_inquiry, … (7 total)
ScopeMintErrorscopes_mintable_by

Operational characteristics

PropertyEvidence
async public surfaceyes
async runtimeyes
database accessyes
network I/Oyes
unsafe codenone detected
environment variablesyes

No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.

Configuration

VariableRead in
CARGO_PKG_VERSIONsrc/lib.rs
INQUIRY_OPERATOR_EMAILsrc/api/customer_workflows.rs
TRUST_PROXYsrc/middleware/auth.rs

4 workspace crates depend on this one: application-agreements, application-catalog, application-cli, application-cms.

Verification

KindCount
Unit tests25
Integration tests9
Examples0
Doctests0

Evidence by module. How often each public module is named by something executable.

ModuleTestsExamplesConsumers
crate root201
api200
api::admin_console203
api::api_keys103
api::auth403
api::customer_auth103
api::customer_workflows103
middleware::api_admin_auth101
middleware::auth403
repo::api_keys705
repo::auth1204
repo::login_attempts200
services::admin_screens3201
services::api_key_auth200
services::api_key_scope400
services::customer_auth804
services::customer_workflows900
services::lockout300

What the tests establish, by name:

Documentation coverage

MeasureDocumentedTotal
Public items with rustdoc59106
Public modules with a //! block2020
pie showData
    title Public items with rustdoc
    "Documented" : 59
    "No rustdoc detected" : 47

Metrics

MetricValue
Rust source files21
Source lines4834
Code lines3736
Public API items106
Public modules20
Tests34
Examples0
Cargo features1
Direct runtime dependencies21
Workspace reverse dependencies4
pie showData
    title Public API by kind
    "constant" : 3
    "enum" : 5
    "function" : 60
    "method" : 9
    "struct" : 29
pie showData
    title Rust source composition
    "Code" : 3736
    "Blank or comment" : 1098

Generation

Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.

All application · Manual