auth0-integration 0.6.5

Auth0 client library for M2M token retrieval and JWT validation (RS256)
Documentation

auth0-integration

Auth0 client library for Rust — handles M2M token retrieval, JWT validation, and user management via the Auth0 Management API.

Installation

Add the crate to your Cargo.toml:

[dependencies]
auth0-integration = "0.6.3"
tokio = { version = "1", features = ["full"] }

Configuration

The library reads Auth0 credentials from environment variables:

Variable Description
AUTH0_DOMAIN Auth0 tenant domain (e.g. your-tenant.us.auth0.com)
AUTH0_CLIENT_ID M2M application client ID
AUTH0_CLIENT_SECRET M2M application client secret
AUTH0_AUDIENCE API identifier registered in Auth0
use auth0_integration::Auth0Config;

let config = Auth0Config::from_env().expect("Missing Auth0 env vars");

Usage

Obtaining an M2M access token

Use Auth0ClientToken to run the Client Credentials flow.

use auth0_integration::{Auth0Config, services::Auth0ClientToken};

#[tokio::main]
async fn main() {
    let config = Auth0Config::from_env().unwrap();
    let client = Auth0ClientToken::new(&config);

    let response = client.get_access_token().await.unwrap();

    // Print the raw JWT string
    println!("{}", response);

    // Access the decoded claims
    let decoded = response.access_token.decoded().unwrap();
    println!("Subject: {}", decoded.sub);
    println!("Issuer:  {}", decoded.iss);
}

Calling the Auth0 Management API

Pass the raw token string to Auth0Client to interact with the Management API.

use auth0_integration::{Auth0Config, services::{Auth0Client, Auth0ClientToken}};
use auth0_integration::models::UpdateUserRequest;

#[tokio::main]
async fn main() {
    let config = Auth0Config::from_env().unwrap();
    let response = Auth0ClientToken::new(&config).get_access_token().await.unwrap();
    let client = Auth0Client::new(&config, response.access_token.token.clone());

    // Look up a user by email
    let users = client.get_user_by_email("user@example.com").await.unwrap();

    // Create a user with a role (returns error if creation fails)
    let role: auth0_integration::Role = "admin".parse().unwrap(); // also: "super_admin", "worker"
    let user = client
        .create_user("Jane Doe", "jane@example.com", &role)
        .await
        .unwrap();

    // Update a user
    let mut req = UpdateUserRequest::new();
    req.name = Some("Jane Doe".to_string());
    req.blocked = Some(false);
    let updated = client.update_user(&user.user_id, req).await.unwrap();

    // Delete a user
    client.delete_user(&user.user_id).await.unwrap();
}

Validating a JWT (RS256)

TokenValidator verifies the token signature, issuer, and audience against Auth0's JWKS endpoint. It caches the JWKS keys in memory and refreshes them automatically on a cache miss or validation failure.

Create one instance per application (e.g. wrap in Arc) and reuse it across requests.

use std::sync::Arc;
use auth0_integration::{Auth0Config, TokenValidator};

#[tokio::main]
async fn main() {
    let config = Auth0Config::from_env().unwrap();
    let validator = Arc::new(TokenValidator::new());

    match validator.validate("eyJ...", &config).await {
        Ok(data) => println!("Valid! sub = {}", data.claims.sub),
        Err(e)   => eprintln!("Invalid token: {e}"),
    }
}

Using with Axum state

use std::sync::Arc;
use axum::{extract::State, http::HeaderMap};
use auth0_integration::{Auth0Config, TokenValidator};

#[derive(Clone)]
struct AppState {
    config: Arc<Auth0Config>,
    validator: Arc<TokenValidator>,
}

async fn protected(State(state): State<AppState>, headers: HeaderMap) {
    let token = headers
        .get("Authorization")
        .and_then(|v| v.to_str().ok())
        .and_then(|v| v.strip_prefix("Bearer "))
        .unwrap();

    let data = state.validator.validate(token, &state.config).await.unwrap();
    println!("sub = {}", data.claims.sub);
}

Checking permissions (scopes)

use auth0_integration::models::AccessToken;

let token = AccessToken::new("eyJ...".to_string());

// Single permission
let can_read = token.validate_permissions("read:users");

// Multiple — all must be present to return true
let can_manage = token.validate_permissions(["read:users", "update:users"]);

Decoding a token payload (without verification)

use auth0_integration::models::AccessToken;

let token = AccessToken::new("eyJ...".to_string());

match token.decoded() {
    Ok(decoded) => println!("{:?}", decoded),
    Err(e)      => eprintln!("Invalid token format: {e}"),
}

Key types

Type Module Description
Auth0Config auth0_integration Auth0 credentials loaded from env
AppError auth0_integration Unified error type
Auth0ClientToken auth0_integration::services Fetches M2M access tokens
Auth0Client auth0_integration::services Auth0 Management API client
TokenValidator auth0_integration Validates JWT strings against Auth0 JWKS with in-memory key cache
AccessToken auth0_integration::models JWT wrapper with lazy decoded payload
AccessTokenResponse auth0_integration::models Full token endpoint response
DecodedAccessToken auth0_integration::models Typed JWT claims (sub, iss, exp, etc.)
Auth0User auth0_integration::models Auth0 user object
Role auth0_integration User role enum (Admin, SuperAdmin, Worker); parses from "admin" / "super_admin" / "worker"
UpdateUserRequest auth0_integration::models Payload for PATCH /api/v2/users/{id}
CreateUserRequest auth0_integration::models Payload for POST /api/v2/users

License

MIT