AuthKit
A better-authβinspired authentication library for Rust. Plug-and-play, framework-agnostic, and opinionated yet extensible.
Overview
AuthKit is a Rust authentication library designed to feel like better-auth, but for the Rust ecosystem. It provides secure, database-backed authentication with a single, unified API that works across any contextβHTTP servers, CLI tools, background workers, or proxies.
Key Features
- π Secure by Default - Argon2id password hashing, timing-safe comparisons, secure token generation
- π― Single Entry Point - One
Authobject for all authentication operations - π§ Framework-Agnostic - Works with Axum, Actix, Rocket, or standaloneβno framework lock-in
- πΎ Database-Backed - SQLite and PostgreSQL support via SQLx (hidden from API)
- π Simple API - Register, login, verify, logoutβsame API everywhere
- β‘ Async-First - Built on Tokio for high-performance async operations
- π¨ Extensible - Swappable password and session strategies
Quick Start
Installation
Add AuthKit to your Cargo.toml:
[]
= "0.1"
= { = "1.28", = ["full"] }
Basic Usage
use *;
async
Design Philosophy
AuthKit is built around five core principles:
1. Single Entry Point
Users interact with only one object: Auth. No repositories, no generics, no leaked internals.
let auth = builder
.database
.build?;
2. Framework-Agnostic by Design
AuthKit doesn't depend on Axum, Actix, Rocket, Hyper, or Tower. It works equally well in:
- REST APIs
- CLI tools
- gRPC services
- Proxies (Pingora)
- Background workers
Framework adapters live outside the core library.
3. Opinionated Defaults, Explicit Overrides
Ships with secure defaults:
- Argon2id password hashing
- Database-backed sessions
- Secure token generation
- Sensible expiry defaults
Override behavior explicitly when needed, but never accidentally weaken security.
4. No Leaky Abstractions
AuthKit hides implementation details:
- SQLx internals
- Database schemas
- Crypto implementations
- Token formats
Users never interact with traits, repositories, lifetimes, or generic parameters in the public API.
5. Same API Everywhere
auth.register.await?;
auth.login.await?;
auth.verify.await?;
auth.logout.await?;
These calls behave identically whether invoked from an HTTP handler, CLI command, test, or background task.
Architecture
Auth
βββ AuthInner (Arc)
βββ Database (trait object)
βββ PasswordStrategy
βββ SessionStrategy
βββ TokenStrategy
Key characteristics:
Authis cheap to clone (usesArcinternally)- Internals are completely hidden
- Components are swappable via builder pattern
- No global state required
Strategy Pattern
AuthKit uses a consistent strategy pattern for all authentication components:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Application Layer β
β (Auth, Operations: register, login, verify, etc.) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Strategy Layer β
β β’ PasswordStrategy (Argon2, Bcrypt, etc.) β
β β’ SessionStrategy (Database-backed) β
β β’ TokenStrategy (Database-backed) β
β β
β Strategies receive &dyn DatabaseTrait as parameter β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β DatabaseTrait (Abstraction) β
β β
β β’ User Operations (create, find) β
β β’ Session Operations (create, find, delete) β
β β’ Token Operations (create, verify, mark used) β
βββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββ
β
β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Backend Implementations β
β β’ SqliteDatabase (SQLite with ? params) β
β β’ PostgresDatabase (Postgres with $N params) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Design Benefits:
- Strategies remain stateless and don't store database references
- Database logic is centralized in backend implementations
- Easy to add new database backends (MySQL, etc.)
- Easy to mock for testing
- No SQLx types leak into public API
Feature Flags
AuthKit uses Cargo features for optional functionality:
[]
= ["sqlite", "argon2"]
# Database backends
= ["sqlx/sqlite", "sqlx/runtime-tokio"]
= ["sqlx/postgres", "sqlx/runtime-tokio"]
# Password hashing strategies
= ["dep:argon2", "dep:password-hash"]
= ["dep:bcrypt"]
# Token strategies
= ["dep:jsonwebtoken"]
Examples
PostgreSQL with Argon2:
= { = "0.1", = false, = ["postgres", "argon2"] }
SQLite with bcrypt:
= { = "0.1", = false, = ["sqlite", "bcrypt"] }
Database Support
SQLite
let auth = builder
.database
.build?;
PostgreSQL
let auth = builder
.database
.build?;
Migrations
AuthKit manages its own schema and migrations:
auth.migrate.await?;
Database Schema:
users- User accounts with email and passwordsessions- Active user sessionstokens- Unified table for email verification, password reset, etc.
All tables include proper indexes and foreign key constraints for optimal performance and data integrity.
API Reference
Auth Operations
Register
Create a new user account:
let user = auth.register.await?;
Validation:
- Email must be valid format
- Password must meet minimum security requirements
- Email must be unique
Login
Authenticate and create a session:
let session = auth.login.await?;
Returns:
Sessionwith token, user_id, and expiration
Verify
Verify a session token and retrieve user:
let user = auth.verify.await?;
Errors:
- Invalid token
- Expired session
- Session not found
Logout
Invalidate a session:
auth.logout.await?;
Send Email Verification
Generate and optionally send a verification token for a user:
// Option 1: Manual email handling (no EmailSender configured)
let verification = auth.send_email_verification.await?;
// You handle sending the email
send_email.await?;
// Option 2: Automatic email sending (with EmailSender configured)
// Email is sent automatically, token still returned
let verification = auth.send_email_verification.await?;
Returns:
VerificationTokenwith token, email, and expiration time- Token expires in 24 hours
Errors:
- User not found
- Email already verified
- Email send failed (if EmailSender is configured)
Verify Email
Verify a user's email using a token:
let verified_user = auth.verify_email.await?;
Returns:
- Updated
Userwithemail_verifiedset totrue
Errors:
- Invalid or expired token
- Token already used
- Email already verified
Resend Email Verification
Resend verification token to a user:
let verification = auth.resend_email_verification.await?;
Returns:
- New
VerificationToken(old tokens remain valid until used or expired)
Errors:
- User not found
- Email already verified
Types
User
Session
VerificationToken
Email Integration
AuthKit provides a flexible email integration system that allows you to use any email service (SendGrid, AWS SES, SMTP, etc.) for sending verification emails, password reset emails, and other authentication-related emails.
Quick Start
Option 1: Manual Email Handling (Default)
By default, AuthKit generates tokens but doesn't send emails. You handle email sending:
let auth = builder
.database
.build?;
let verification = auth.send_email_verification.await?;
// You send the email using your service
send.await?;
Option 2: Automatic Email Sending
Configure an EmailSender to send emails automatically:
use ;
use async_trait;
// Implement the EmailSender trait
// Configure Auth with your email sender
let auth = builder
.database
.email_sender
.build?;
// Now emails are sent automatically
auth.send_email_verification.await?;
EmailSender Trait
Example Implementations
Console Logger (Development)
SendGrid (Production)
Environment-Based Configuration
let auth = builder
.database
.email_sender
.build?;
For detailed email integration guide, see docs/EMAIL_INTEGRATION.md.
Security
Default Security Features
| Feature | Default |
|---|---|
| Password hashing | Argon2id |
| Timing-safe compares | β Enabled |
| Session expiration | β Enabled (24 hours) |
| Token entropy | High (cryptographically secure) |
| Password reuse | π« Prevented |
| Weak passwords | π« Rejected |
Password Requirements
- Minimum length: 8 characters
- Must contain at least one uppercase letter
- Must contain at least one lowercase letter
- Must contain at least one number
- Must contain at least one special character
Email Validation
- RFC 5322 compliant email validation
- Checks for valid format and structure
Advanced Configuration
Custom Password Strategy
use *;
use PasswordStrategyType;
let auth = builder
.database
.password_strategy
.build?;
Custom Session Strategy
use *;
use SessionStrategyType;
let auth = builder
.database
.session_strategy
.build?;
Error Handling
AuthKit provides a comprehensive error type:
use *;
match auth.login.await
Examples
Check the examples/ directory for more usage examples:
email_verification.rs- Complete email verification workflowemail_sender.rs- Custom email sender implementations (SendGrid, AWS SES, SMTP, etc.)basic.rs- Simple registration and login flow (planned)web_server.rs- Integration with Axum (planned)cli_tool.rs- CLI authentication example (planned)
Run an example:
Testing
Run the test suite:
Run tests with all features:
Roadmap
Current Status: Foundation Phase β
Implemented:
- β Core Auth API
- β Builder pattern
- β SQLite backend
- β PostgreSQL backend
- β Argon2 password hashing
- β Database sessions
- β Email validation
- β Password validation
- β Token system (database-backed)
- β Email verification flow (send, verify, resend)
Planned:
- π JWT sessions
- π Refresh tokens
- π Password reset flow
- π Magic link authentication
- π Axum adapter
- π Actix adapter
- π Rate limiting
- π Audit logging
- π OAuth integration
- π Two-factor authentication
Contributing
Contributions are welcome! Please read our contribution guidelines first.
For Contributors (Including AI Agents)
When contributing to AuthKit, you MUST:
- β Preserve the single-entry-point design
- β Avoid exposing generics or traits publicly
- β Keep framework dependencies out of core
- β Prefer composition over configuration
- β Default to secure behavior
You MUST NOT:
- β Add framework-specific logic to core
- β Leak SQLx types into the public API
- β Introduce global state
- β Require users to wire repositories manually
If a change makes the API feel less like better-auth, it's probably wrong.
License
This project is dual-licensed under your choice of:
- MIT License (LICENSE-MIT)
- Apache License, Version 2.0 (LICENSE-APACHE)
at your option.
Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
Acknowledgments
Inspired by better-auth - an excellent authentication library for JavaScript/TypeScript.
Support
- π Documentation
- π Issue Tracker
- π¬ Discussions
Built with β€οΈ by Akshay B