Skip to content

sdk/rust

Async Rust server SDK for networkless JWT verification, request authentication, and webhook signature validation.

Status

Implemented and verified locally. Real IdP round-trip verification (JWKS fetch, token sign/verify against a live XID instance) has not been performed yet and must be completed before production use.

Install

Add to Cargo.toml:

[dependencies]
xid = "0.1"
tokio = { version = "1", features = ["full"] }

Quick start

use std::sync::Arc;
use xid::{XidClient, XidClientConfig, AuthState};

#[tokio::main]
async fn main() {
    let config = XidClientConfig::new("https://xid.dev")
        .with_audience("your-client-id");

    let client = Arc::new(XidClient::new(config).expect("build client"));

    match client.verify_token("eyJ...").await {
        Ok(verified) => {
            println!("user: {}", verified.claims.sub);
            println!("email: {:?}", verified.claims.email);
        }
        Err(e) => eprintln!("invalid token: {e}"),
    }
}

Authenticate a request

let state = client.authenticate_request(raw_headers, cookies).await;

match state {
    AuthState::Authenticated(token) => {
        println!("user: {}", token.claims.sub);
        // token.claims.has_scope("openid") -> bool
        // token.claims.org_id -> Option<String>
    }
    AuthState::Unauthenticated => { /* return 401 */ }
    AuthState::Invalid(e) => { /* return 401 */ }
}

Verify webhook

use xid::WebhookVerifier;

let webhook_secret =
    std::env::var("XID_WEBHOOK_SECRET").expect("XID_WEBHOOK_SECRET is required");
let verifier = WebhookVerifier::new(&webhook_secret).expect("valid secret");

match verifier.verify_from_headers(headers, body) {
    Ok(()) => {
        let payload = xid::WebhookPayload::from_bytes(body).unwrap();
        println!("event: {}", payload.event_type);
    }
    Err(e) => { /* return 400 */ }
}

Core API

Symbol Description
XidClientConfig::new(issuer) Minimal constructor. Chain builder methods for optional settings.
.with_audience(aud) Set expected audience claim.
.with_session_cookie(name) Override session cookie name (default __session).
.with_leeway(seconds) Clock skew tolerance for exp/nbf.
XidClient::new(config) Build client with default reqwest HTTP client.
XidClient::with_http_client(config, http) Build client with a custom reqwest client (useful for testing).
client.verify_token(token) Verify token string; returns XidResult<VerifiedToken>.
client.authenticate_request(headers, cookies) Extract and verify token from raw headers and cookies; returns AuthState.
WebhookVerifier::new(secret) Accept whsec_<base64> or raw base64 secret.
verifier.verify_from_headers(headers, body) Extract svix headers automatically and validate HMAC-SHA256 signature.

Platform notes

  • Async-first API built on tokio. Uses rustls (no OpenSSL dependency) via reqwest.
  • ES256 is the primary algorithm; RS256 is supported. PS256 support is planned. ES384/ES512 are not yet implemented.
  • Framework integration features (axum, actix-web) are planned but not included in this release.
  • XidError uses thiserror for structured error variants including JwtValidation, JwksFetch, KeyNotFound, IssuerMismatch, and webhook-specific variants.
Navigation

Type to search...

Use arrow keys to navigateEnter to selectEscape to close