Plugins
Everything beyond the core session machinery is a plugin. A plugin owns a set of routes, may add schema fields, and can hook into requests, sign-in and user lifecycle events. You register plugins with .plugin(...) and finish with .build().await.
Register plugins
Section titled “Register plugins”Generate and migrate any schema the plugin needs (Database), then add it to the builder:
alibi generate --plugins admin,two-factor -o src/auth_schema.rsuse crate::auth_schema::AppAuthSchema;use alibi::plugins::{AdminPlugin, EmailPasswordPlugin, TwoFactorPlugin};use alibi::sqlx::SqlxStore;use alibi::{AuthConfig, AuthResult, BetterAuth};
async fn build_auth( config: AuthConfig, store: SqlxStore<AppAuthSchema>,) -> AuthResult<BetterAuth<AppAuthSchema>> { BetterAuth::<AppAuthSchema>::new(config) .store(store) .plugin(EmailPasswordPlugin::new().enable_signup(true)) .plugin(TwoFactorPlugin::new()) .plugin(AdminPlugin::new()) .build() .await}build() initializes plugins in the order you registered them. Most plugins accept configuration in two equivalent forms — chained builder methods, or a config struct:
use alibi::plugins::{AdminConfig, AdminPlugin};
fn admin_plugins() -> (AdminPlugin, AdminPlugin) { // 1. Chained builder methods (one per option) let chained = AdminPlugin::new() .default_role("member") .allow_impersonating_admins(true); // 2. A config struct let from_struct = AdminPlugin::with_config(AdminConfig { default_role: "member".into(), allow_impersonating_admins: true, ..Default::default() }); (chained, from_struct)}Plugins whose configuration includes callbacks or trait objects (email OTP, magic link, phone number, JWT, CAPTCHA, SIWE, …) take a config struct and use ..Default::default() for the rest; the API key plugin uses ApiKeyPlugin::builder()…build(). Each plugin page lists its options.
Plugins that are always installed
Section titled “Plugins that are always installed”The builder appends these core plugins unless you register your own of the same name:
| Plugin | Name | Provides |
|---|---|---|
SessionManagementPlugin |
session-management |
/get-session, /sign-out, /list-sessions, /revoke-*, /update-session |
EmailPasswordPlugin (disabled) |
email-password |
Routes registered but credential login is off until you configure it |
PasswordManagementPlugin |
password-management |
/request-password-reset, /reset-password, /change-password, /verify-password |
EmailVerificationPlugin |
email-verification |
/send-verification-email, /verify-email |
AccountManagementPlugin |
account-management |
/list-accounts, /unlink-account |
OAuthPlugin (no providers) |
oauth |
/sign-in/social, /link-social, /callback/{provider}, token endpoints |
UserManagementPlugin |
user-management |
/update-user, /change-email, /delete-user |
Registering one of these yourself replaces the default with your configuration: .plugin(EmailPasswordPlugin::new().enable_signup(true)) enables password sign-in, and .plugin(UserManagementPlugin::new().change_email_enabled(true)) enables email changes. Explicit plugins are consulted before the defaults when a request is dispatched.
Order matters in two places
Section titled “Order matters in two places”- Route ownership. When two plugins serve the same route, the first registered wins. Custom session relies on this: register it before
SessionManagementPluginto take overGET /get-session. - Hooks.
before_request,after_requestand endpoint hooks run in registration order.
Inspect the running instance
Section titled “Inspect the running instance”use crate::auth_schema::AppAuthSchema;use alibi::BetterAuth;
fn describe(auth: &BetterAuth<AppAuthSchema>) { println!("plugins: {:?}", auth.plugin_names()); for route in auth.registered_routes() { println!("{:?} {}", route.method, route.path); }}Every route in the instance, with request and response schemas, is also available as an OpenAPI document, and the complete table of routes is in the HTTP API reference.
Catalog at a glance
Section titled “Catalog at a glance”| I need to… | Plugin |
|---|---|
| Sign in with email and password, usernames | Email and password, Username |
| Sign in without a password | Magic link, Email OTP, Passkey, Phone number, SIWE |
| Sign in with Google, GitHub, … | Social sign-on, Generic OAuth, One Tap |
| Require a second factor | Two-factor |
| Authenticate machines and CLIs | API key, Device authorization, Bearer, JWT |
| Run multi-tenant apps | Organization, Admin |
| Harden sign-up | CAPTCHA, Have I Been Pwned |
The complete list is the plugin overview. To build your own, read Writing a plugin.
Frontend
Section titled “Frontend”See the official client plugin documentation.