| Crates.io | threatflux-auth-sdk |
| lib.rs | threatflux-auth-sdk |
| version | 0.2.0 |
| created_at | 2025-12-07 14:35:00.951693+00 |
| updated_at | 2026-01-03 15:12:40.818115+00 |
| description | Reusable authentication SDK for ThreatFlux services |
| homepage | https://github.com/ThreatFlux/core |
| repository | https://github.com/ThreatFlux/core |
| max_upload_size | |
| id | 1971696 |
| size | 897,387 |
threatflux-auth-sdkthreatflux-auth-sdk is the reusable authentication and authorization layer shared by ThreatFlux services. It exposes:
AuthState, which wraps the configured credential store, token signer, and OAuth hooksThe crate is designed to drop into any backend that needs a turnkey auth subsystem with consistent APIs and models.
threatflux_auth_sdk::router().AuthState::with_postgres or AuthState::in_memory.threatflux_auth_sdk::AuthApiDoc).test-utils feature).axum, tower, tokio: request routing and async runtime.sqlx: Postgres-backed persistence for users, sessions, OAuth states, and password resets.argon2, jsonwebtoken, oauth2, rand, sha2, base64: credential hashing + token signing.serde, validator, chrono, uuid: strongly typed request payloads and validation helpers.thiserror, anyhow, tracing, utoipa: ergonomic errors, logging, and OpenAPI support.crates/threatflux-auth-sdk/
├── src/
│ ├── handlers.rs # Axum handlers and router() definition
│ ├── service.rs # Business logic shared across transports
│ ├── state.rs # AuthState + Postgres/in-memory configuration
│ ├── store/ # ProviderStore trait + memory/postgres backends
│ ├── oauth/ # OAuth-specific helpers + provider glue
│ ├── hooks.rs # Callback definitions for login/logout events
│ ├── models.rs # Request/response structs and DB entities
│ ├── validation.rs # Field + password validators
│ ├── extractor.rs # Authenticated user extractor for Axum handlers
│ └── openapi.rs # `AuthApiDoc` builder used by services
├── tests/ # Postgres integration tests + router smoke tests
└── Cargo.toml # feature flags (`test-utils`) and dependency declarations
use threatflux_auth_sdk::{router, AuthState};
use threatflux_auth_sdk::store::PostgresStoreConfig;
#[tokio::main]
async fn main() -> Result<(), threatflux_auth_sdk::AuthError> {
dotenvy::dotenv().ok();
let secret = std::env::var("AUTH_SECRET").expect("set AUTH_SECRET");
let auth_state = if let Ok(db_url) = std::env::var("DATABASE_URL") {
let config = PostgresStoreConfig::new(db_url);
AuthState::with_postgres(secret, config).await?
} else {
AuthState::in_memory(secret)
};
let app = axum::Router::new()
.merge(router())
.layer(axum::Extension(auth_state));
axum::Server::bind(&"127.0.0.1:4000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
Ok(())
}
# format + lint
cargo fmt -p threatflux-auth-sdk
cargo clippy -p threatflux-auth-sdk --all-targets
# run unit + integration tests (requires Postgres for the `postgres_*` suites)
cargo test -p threatflux-auth-sdk
Set DATABASE_URL when running tests so the SQLx-backed routes exercise the full store implementation. When Postgres is unavailable the suite automatically skips the heavy integration tests and continues with the in-memory coverage.
The SDK supports GitHub plus any number of generic OAuth/OIDC providers configured via environment variables. List provider ids in OAUTH_PROVIDERS (comma separated). Each id uses uppercased env prefixes such as OAUTH_TARGET_* or OAUTH_CUSTOM_*:
OAUTH_PROVIDERS=target,custom
OAUTH_TARGET_CLIENT_ID=...
OAUTH_TARGET_CLIENT_SECRET=...
OAUTH_TARGET_AUTH_URL=...
OAUTH_TARGET_TOKEN_URL=...
OAUTH_TARGET_REDIRECT_URI=...
OAUTH_TARGET_USERINFO_URL=...
OAUTH_TARGET_SCOPES=openid profile email # optional, defaults to these
OAUTH_TARGET_EMAIL_CLAIMS=mail,email # optional claim names (comma/space separated)
OAUTH_TARGET_USERNAME_CLAIMS=preferred_username # optional
OAUTH_TARGET_DISPLAY_NAME_CLAIMS=name,firstname,lastname
OAUTH_TARGET_GROUP_CLAIMS=groups,memberof
OAUTH_CUSTOM_CLIENT_ID=...
# ... same keys for each provider id listed in OAUTH_PROVIDERS
GitHub continues to use the existing OAUTH_GITHUB_* variables and scopes appropriate for its API.
The SDK can also act as an OAuth2/OIDC provider when enabled via environment variables:
OAUTH_PROVIDER_ENABLED=true
OAUTH_PROVIDER_ISSUER=https://auth.example.com
OAUTH_PROVIDER_SIGNING_KEY=super-secret-signing-key
OAUTH_PROVIDER_SIGNING_ALG=HS256 # optional, HS256/HS384/HS512
OAUTH_PROVIDER_GRANTS=authorization_code,refresh_token,client_credentials
OAUTH_PROVIDER_SCOPES=openid,profile,email,groups,offline_access
OAUTH_PROVIDER_ACCESS_TTL=3600 # seconds
OAUTH_PROVIDER_REFRESH_TTL=1209600 # seconds
OAUTH_PROVIDER_KID=provider-key-1 # optional
Exposed endpoints when enabled:
/api/v1/oauth/authorize – authorization code with optional PKCE (requires authenticated user with internal access token)/api/v1/oauth/token – authorization_code, refresh_token, and client_credentials grants/api/v1/oauth/userinfo – OIDC user claims derived from the internal user record/api/v1/.well-known/openid-configuration and /api/v1/.well-known/jwks.jsonOAuth clients are stored in the same backing store. Admin routes (require an admin user token):
POST /api/v1/admin/oauth/clients to create a client (returns the client secret once)GET /api/v1/admin/oauth/clients to list clientsGET/PATCH /api/v1/admin/oauth/clients/{client_id} to inspect or updatePOST /api/v1/admin/oauth/clients/{client_id}/rotate-secret to issue a new secretClients can be public (PKCE-only) or confidential (secret-based). Scopes are validated against each client's allowed scopes and the provider-wide grant whitelist.