Authdog

Rust

Last updated Jul 11, 2026
View as Markdown

The Authdog Rust SDK validates sessions in async Rust services. A framework-agnostic core crate (authdog-core) is wrapped by per-framework crates for axum, actix-web, Rocket, warp, and Poem. For the model behind it, see Backend requests.

Install

Add the crate for your framework alongside the framework itself:

Bash
cargo add authdog-axum axum      # or: cargo add authdog-actix actix-web

All crates target edition 2021 / Rust 1.75+.

Configure

Create the client once from your environment's public key (pk_...). It's validated at startup:

Rust
let authdog = Authdog::new(&std::env::var("PK_AUTHDOG")?)?;

Use the builder to opt out of the userinfo call or supply a custom client: Authdog::builder(&pk).fetch_user(false).http_client(client).build(). For self-hosted identity, allowlist hosts with the AUTHDOG_ALLOWED_IDENTITY_HOSTS environment variable.

Every framework resolves the same AuthContext:

Rust
AuthContext {
    token: Option<String>,
    user: Option<serde_json::Value>,
    is_authenticated: bool,
    user_info: Option<UserInfoResponse>,
}

axum

attach_session decorates requests; require_auth is the 401 gate; AuthContext works as an extractor in handlers:

Rust
use axum::{middleware, routing::get, Json, Router};
use authdog_axum::{attach_session, logout, require_auth, Authdog, AuthContext};
use serde_json::Value;

let authdog = Authdog::new(&std::env::var("PK_AUTHDOG")?)?;

let app = Router::new()
    .route(
        "/me",
        get(|ctx: AuthContext| async move { Json(ctx.user.unwrap_or(Value::Null)) })
            .layer(middleware::from_fn(require_auth)),
    )
    .route("/logout", get(logout))
    .layer(middleware::from_fn_with_state(authdog.clone(), attach_session))
    .with_state(authdog);

actix-web

Register the client as app data and use the RequireAuth extractor as the guard — user.0 is the AuthContext:

Rust
use actix_web::{web, App};
use authdog_actix::{logout, Authdog, RequireAuth};

let authdog = Authdog::new(&std::env::var("PK_AUTHDOG")?)?;

App::new()
    .app_data(web::Data::new(authdog.clone()))
    .route("/me", web::get().to(|user: RequireAuth| async move {
        web::Json(user.0.user.clone())
    }))
    .route("/logout", web::get().to(logout));

Resolving a session tells you who the caller is — pair it with your environment's authorization model to decide what they can do.

Service-to-service

Machine-to-machine callers send their token as Authorization: Bearer <token>; it resolves on the same path as a browser session across every crate. See Backend requests.

Next steps