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](/docs/backend).

## 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](/docs/concepts/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](/docs/backend#service-to-service-m2m).

## Next steps

- [Backend requests](/docs/backend) — the verification model across every backend SDK.
- [Calling the REST API](/docs/api) — read users and organizations once a request is authenticated.
