revoke-auth

Crates.iorevoke-auth
lib.rsrevoke-auth
version0.5.0
created_at2025-07-21 16:23:13.704877+00
updated_at2025-07-21 16:23:13.704877+00
descriptionHigh-performance microservices infrastructure framework built with pure Rust
homepage
repositoryhttps://github.com/revoke/revoke
max_upload_size
id1762240
size69,540
LioRael (LioRael)

documentation

README

Revoke Auth

Revoke Auth is a high-performance JWT authentication library for Axum web applications, built with pure Rust. It provides seamless JWT token validation with JWKS (JSON Web Key Set) support and custom claims extraction.

Features

  • JWT Token Validation: Secure JWT token validation with RS256 algorithm support
  • JWKS Integration: Automatic public key fetching and caching from JWKS endpoints
  • High Performance: Built on tokio async runtime with efficient key caching
  • Custom Claims: Support for custom JWT claims through trait implementation
  • Axum Integration: Native Axum extractor for seamless authentication middleware
  • Zero Copy: Minimal allocations and efficient memory usage

Installation

Add this to your Cargo.toml:

[dependencies]
revoke-auth = "0.5.0"
axum = "0.8"
tokio = { version = "1", features = ["full"] }
serde = { version = "1", features = ["derive"] }

Quick Start

1. Define Your Claims

First, implement the JwtClaims trait for your custom claims structure:

use revoke_auth::JwtClaims;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct UserClaims {
    pub sub: String,        // Subject (user ID)
    pub email: String,      // User email
    pub role: String,       // User role
    pub exp: usize,         // Expiration time
    pub iat: usize,         // Issued at
}

impl JwtClaims for UserClaims {
    fn sub(&self) -> &str {
        &self.sub
    }
}

2. Setup Application State

Configure your application with JWKS store and authentication config:

use revoke_auth::{JwksStore, AuthConfig, Auth};
use axum::{Router, routing::get, response::Json};

#[derive(Clone)]
pub struct AppState {
    pub jwks_store: JwksStore,
    pub auth_config: AuthConfig,
}

impl AsRef<JwksStore> for AppState {
    fn as_ref(&self) -> &JwksStore {
        &self.jwks_store
    }
}

impl AsRef<AuthConfig> for AppState {
    fn as_ref(&self) -> &AuthConfig {
        &self.auth_config
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize JWKS store with your identity provider's JWKS URL
    let jwks_store = JwksStore::new(
        "https://your-auth-provider.com/.well-known/jwks.json".to_string()
    ).await?;

    // Configure authentication parameters
    let auth_config = AuthConfig {
        issuer: "https://your-auth-provider.com".to_string(),
        audience: Some("your-audience".to_string()),
    };

    let state = AppState {
        jwks_store,
        auth_config,
    };

    let app = Router::new()
        .route("/protected", get(protected_handler))
        .with_state(state);

    // Start server
    let listener = tokio::net::TcpListener::bind("127.0.0.1:3000").await?;
    axum::serve(listener, app).await?;

    Ok(())
}

3. Protected Route Handlers

Use the Auth<T> extractor in your route handlers:

use axum::{response::Json, http::StatusCode};
use serde_json::{json, Value};

// Protected route that requires authentication
async fn protected_handler(
    Auth(claims): Auth<UserClaims>
) -> Result<Json<Value>, StatusCode> {
    Ok(Json(json!({
        "message": "Access granted",
        "user_id": claims.sub(),
        "email": claims.email,
        "role": claims.role
    })))
}

4. Client Usage

Send requests with JWT tokens in the Authorization header:

curl -H "Authorization: Bearer your-jwt-token-here" \
     http://localhost:3000/protected

Configuration

AuthConfig Options

Field Type Description Required
issuer String JWT issuer URL Yes
audience Option<String> Expected audience claim No

Error Handling

The library returns HTTP status codes for different error conditions:

  • 401 Unauthorized: Invalid or missing JWT token
  • 401 Unauthorized: Token validation failed (expired, wrong issuer, etc.)
  • 401 Unauthorized: JWKS key not found for token

API Reference

JwtClaims

A trait that must be implemented by your custom claims structure:

pub trait JwtClaims: DeserializeOwned + Send + Sync + 'static {
    fn sub(&self) -> &str;
}

Auth

An Axum extractor for extracting authenticated claims from requests.

JwksStore

Manages JWKS key fetching and caching:

impl JwksStore {
    pub async fn new(url: String) -> Result<Self>;
    pub async fn refresh(&self) -> Result<()>;
    pub async fn get_key(&self, kid: &str) -> Option<DecodingKey>;
}

AuthConfig

Configuration for JWT validation:

pub struct AuthConfig {
    pub issuer: String,
    pub audience: Option<String>,
}

Security Best Practices

  1. Use HTTPS for JWKS URLs and API endpoints
  2. Validate issuer and audience claims
  3. Implement proper key rotation
  4. Use reasonable token expiration times
  5. Apply proper CORS and security headers

Compatibility

  • Axum: 0.8+
  • Tokio: 1.0+
  • Rust: 1.70+ (2024 edition)

License

This project is licensed under either Apache License 2.0 or MIT license at your option.

Commit count: 0

cargo fmt