Crate jwtiny

Crate jwtiny 

Source
Expand description

§jwtiny - Minimal, Type-Safe JWT Validation

Minimal, type-safe JSON Web Token (JWT) validation for Rust.

jwtiny validates JWT tokens through a builder-pattern API that enforces correct validation order at compile time. Born from the need for jsonwebtoken with miniserde support, it evolved into a generic JWT library prioritizing safety, clarity, and zero-cost abstractions.

§Overview

JWTs (JSON Web Tokens) encode claims as JSON objects secured by digital signatures or message authentication codes. Validating them requires parsing Base64URL-encoded segments, verifying signatures with cryptographic keys, and checking temporal claims like expiration. Common pitfalls include algorithm confusion attacks (accepting asymmetric algorithms when only symmetric keys are trusted), server-side request forgery (SSRF) via untrusted issuer URLs, and timing vulnerabilities in signature comparison.

jwtiny addresses these through a type-safe state machine: parsing yields a ParsedToken, issuer validation produces a TrustedToken, signature verification creates a VerifiedToken, and claims validation returns the final Token. Each stage must complete before the next begins, enforced by Rust’s type system. The builder pattern configures all steps upfront, then executes them atomically—preventing partial validation and ensuring cryptographic keys are only used after issuer checks complete.

§Quick Start

use jwtiny::*;

let token = TokenValidator::new(
    ParsedToken::from_string(token_str)?
)
    .ensure_issuer(|iss| Ok(iss == "https://trusted.com"))
    .verify_signature(SignatureVerification::with_secret_hs256(b"secret"))
    .validate_token(ValidationConfig::default())
    .run()?;

println!("Subject: {:?}", token.subject());

§Validation Flow

The library enforces a validation pipeline through type-level state transitions:

ParsedToken (parsed header and payload)
    │ .ensure_issuer()
    ▼
TrustedToken (issuer validated; internal type)
    │ .verify_signature()
    ▼
VerifiedToken (signature verified; internal type)
    │ .validate_token()
    ▼
ValidatedToken (claims validated; internal type)
    │ .run() / .run_async()
    ▼
Token (public API; safe to use)

Only the final Token type is exposed publicly. Intermediate types (TrustedToken, VerifiedToken, ValidatedToken) are internal, preventing partial validation from escaping the builder.

§Algorithm Support

All algorithms implement a common Algorithm trait:

  • HMAC (always enabled): HS256, HS384, HS512
  • RSA (with rsa feature): RS256, RS384, RS512
  • ECDSA (with ecdsa feature): ES256, ES384

§Signature Verification

Choose verification based on the algorithm family:

// Symmetric key (HMAC)
SignatureVerification::with_secret_hs256(b"your-256-bit-secret")

// Public key (RSA/ECDSA)
SignatureVerification::with_key(
    Key::rsa_public(public_key_der),
    AlgorithmPolicy::rs256_only(),
)

// Remote JWKS fetching
SignatureVerification::with_jwks(
    http_client,
    AlgorithmPolicy::recommended_asymmetric(),
    true,
)

Use algorithm-specific constructors (preferred) or pass an explicit AlgorithmPolicy to prevent algorithm confusion.

§Claims Validation

Configure temporal and claim-specific checks:

ValidationConfig::default()
    .require_audience("my-api")           // Validate `aud` claim
    .max_age(3600)                         // Token must be < 1 hour old
    .clock_skew(60)                        // Allow 60s clock skew
    .custom(|claims| {                     // Custom validation logic
        if claims.subject.as_deref() != Some("admin") {
            Err(Error::ClaimValidationFailed(
                ClaimError::Custom("Admin only".to_string())
            ))
        } else {
            Ok(())
        }
    })

§Features

  • HMAC (always enabled): HS256, HS384, HS512
  • rsa: RSA algorithms (RS256, RS384, RS512)
  • ecdsa: ECDSA algorithms (ES256, ES384)
  • aws-lc-rs: Use aws-lc-rs backend instead of ring for RSA/ECDSA
  • all-algorithms: Enable all asymmetric algorithms (RSA + ECDSA)
  • remote: Remote JWKS over HTTPS (rustls). Provide an HTTP client.

§Security

§Algorithm Confusion Prevention

Always restrict algorithms explicitly. Without restrictions, a token declaring RS256 might be accepted when you only intended to allow HS256.

§SSRF Prevention

When using JWKS, validate issuers before fetching keys. Without issuer validation, an attacker can craft a token with an arbitrary iss claim, causing your application to fetch keys from attacker-controlled URLs—a classic SSRF vulnerability.

§“none” Algorithm Rejection

The "none" algorithm (unsigned tokens) is always rejected per RFC 8725.

§Timing Attack Protection

HMAC signature verification uses constant-time comparison via the constant_time_eq crate, preventing timing-based key recovery attacks.

§References

  • RFC 7515 — JSON Web Signature (JWS)
  • RFC 7519 — JSON Web Token (JWT)
  • RFC 8725 — JSON Web Signature Best Practices

Re-exports§

pub use token::ParsedToken;
pub use token::Token;
pub use validator::TokenValidator;
pub use claims::ValidationConfig;
pub use validator::SignatureVerification;
pub use algorithm::AlgorithmId;
pub use algorithm::AlgorithmPolicy;
pub use claims::Claims;
pub use error::ClaimError;
pub use error::Error;
pub use error::Result;
pub use keys::Key;
pub use token::TokenHeader;

Modules§

algorithm
claims
error
Error types for JWT processing
keys
token
utils
validator
Token validator with builder pattern