Skip to content

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.

Generate and migrate any schema the plugin needs (Database), then add it to the builder:

Terminal window
alibi generate --plugins admin,two-factor -o src/auth_schema.rs
use 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.

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.

  • Route ownership. When two plugins serve the same route, the first registered wins. Custom session relies on this: register it before SessionManagementPlugin to take over GET /get-session.
  • Hooks. before_request, after_request and endpoint hooks run in registration order.
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.

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.

See the official client plugin documentation.