authia 0.3.4

High-performance JWT verification library for Ed25519 using WebAssembly
Documentation
# authia Improvement Roadmap


This document outlines planned improvements for the authia library based on production experience and performance analysis.

## Background


After deploying authia v0.3.x to production, we identified several areas for improvement:

1. **Performance**: While authia is fast, the JS ↔ WASM boundary overhead (~0.1-0.15ms) makes it slower than `jose` in Node.js environments
2. **Schema Strictness**: v0.3.1-v0.3.3 use strict type checking that can reject valid tokens with missing optional fields
3. **Environment Variable Parsing**: Auto-detection of JSON vs Base64 format needs to be more robust

## Priority 1: Critical Fixes


### 1.1 Schema Flexibility (v0.4.0)


**Problem**: Current implementation rejects tokens with missing optional fields (e.g., `email`)

**Solution**: Make JWT claims more flexible

```rust
use serde::{Deserialize};

#[derive(Deserialize)]

pub struct TokenClaims {
    pub sub: String,              // Required
    pub exp: Option<u64>,         // Optional
    pub iat: Option<u64>,         // Optional
    pub email: Option<String>,    // Optional
    pub authId: Option<String>,   // Optional
    #[serde(flatten)]
    pub others: serde_json::Value, // Catch-all for unknown fields
}
```

**Benefits**:

- Backward compatible with existing tokens
- Won't reject tokens with varying claim structures
- Maintains type safety for known fields

**Priority**: HIGH - Affects production stability

### 1.2 Robust Environment Variable Parsing


**Problem**: Current auto-detection can fail in some environments

**Solution**: Implement fallback parsing strategy

```rust
fn parse_key(s: &str) -> Result<Jwk, Error> {
    // Try JSON first
    if let Ok(j) = serde_json::from_str::<Jwk>(s) {
        return Ok(j);
    }

    // Try Base64 decode, then JSON
    let decoded = base64::decode_config(s, base64::URL_SAFE)?;
    serde_json::from_slice(&decoded).map_err(|e| {
        // Provide detailed error with context
        Error::KeyParse(format!(
            "Failed to parse as JSON or Base64-encoded JSON. Length: {}, First 20 chars: {:?}",
            s.len(),
            &s.chars().take(20).collect::<String>()
        ))
    })
}
```

**Benefits**:

- More reliable across different deployment environments
- Better error messages for debugging
- Handles edge cases gracefully

**Priority**: HIGH - Affects deployment reliability

## Priority 2: Performance Optimizations


### 2.1 Reduce Boundary Crossing Overhead


**Problem**: Multiple JS ↔ WASM calls add up to ~0.1-0.15ms overhead

**Solution**: Single-function API that does everything in one call

```rust
#[wasm_bindgen]

pub fn verify_token(token: &str, options_json: &str) -> JsValue {
    // Parse, verify, and return minimal result in one call
    let result = match verify_internal(token, options_json) {
        Ok(claims) => VerifyResult {
            success: true,
            sub: claims.sub,
            exp: claims.exp,
            // ... minimal fields only
        },
        Err(e) => VerifyResult {
            success: false,
            error: e.to_string(),
        }
    };

    serde_wasm_bindgen::to_value(&result).unwrap()
}
```

**Benefits**:

- Reduces boundary crossings from multiple to just one
- Could reduce overhead from 0.15ms to ~0.05ms
- Simpler API surface

**Priority**: MEDIUM - Performance improvement, not critical

### 2.2 Binary Optimization


**Current**: `opt-level = 3` (speed)

**Additions to consider**:

```toml
[profile.release]
opt-level = 3
lto = true              # Link-time optimization
codegen-units = 1       # Better optimization, slower build
```

**Trade-offs**:

- Smaller binary size (important for Workers)
- Potentially faster execution
- Slower build times

**Priority**: LOW - Marginal gains

### 2.3 Native Node.js Addon (Alternative Approach)


**Problem**: WASM boundary overhead is inherent to the architecture

**Solution**: Build native Node.js addon using `napi-rs` or `neon`

**Benefits**:

- Eliminates boundary overhead completely
- Could match or exceed `jose` performance
- Still written in Rust

**Drawbacks**:

- More complex build/distribution
- Platform-specific binaries
- Loses universal runtime support

**Priority**: LOW - Significant effort, limited benefit for Workers use case

## Priority 3: Developer Experience


### 3.1 Comprehensive Benchmarking


**Goal**: Provide clear performance data across different environments

**Metrics to track**:

- p50, p95, p99 latency
- Different environments (Node.js, Workers, Bun)
- Comparison with `jose` and other libraries
- Memory usage

**Priority**: MEDIUM - Helps users make informed decisions

### 3.2 Better Error Messages


**Current**: Generic error messages

**Improvement**: Provide actionable error information

```rust
pub enum AuthiaError {
    TokenExpired { expired_at: u64, now: u64 },
    InvalidSignature { algorithm: String },
    InvalidIssuer { expected: String, got: String },
    MissingClaim { claim: String },
    // ...
}
```

**Priority**: MEDIUM - Improves debugging experience

## Priority 4: Security & Quality


### 4.1 Security Audit


- Review constant-time comparison implementation
- Ensure no timing attacks possible
- Validate error messages don't leak sensitive info

**Priority**: HIGH - Security is critical

### 4.2 Fuzzing & Property-Based Testing


- Add fuzzing tests for JWT parsing
- Property-based tests for cryptographic operations
- Edge case coverage

**Priority**: MEDIUM - Improves reliability

## Deployment Strategy


### Short-term (Now)


1. ✅ Document known issues in README
2. ✅ Recommend `jose` for Node.js environments
3. ✅ Keep authia for Workers use case

### Medium-term (1-3 months)


1. Implement schema flexibility (v0.4.0)
2. Improve environment variable parsing
3. Add comprehensive benchmarks
4. Security audit

### Long-term (3-6 months)


1. Evaluate native Node.js addon approach
2. Consider microservice architecture for high-throughput scenarios
3. Expand to support more JWT algorithms (if needed)

## Decision Framework


**When to use authia:**

- ✅ Cloudflare Workers with Ed25519 tokens
- ✅ Need consistent behavior across platforms
- ✅ Learning Rust + WebAssembly
- ✅ Edge runtime deployments

**When to use jose:**

- ✅ Node.js backend with high throughput
- ✅ Need maximum performance
- ✅ Production stability is critical
- ✅ Tokens with varying claim structures

## Contributing


If you'd like to contribute to any of these improvements, please:

1. Open an issue to discuss the approach
2. Reference this roadmap in your PR
3. Include benchmarks for performance changes
4. Add tests for new functionality

## Version History


- **v0.3.3**: Environment variable auto-detection
- **v0.3.2**: Fixed Base64 parsing issues
- **v0.3.1**: Strict schema validation (caused production issues)
- **v0.3.0**: Single-pass JSON parsing optimization
- **v0.2.0**: Added `publicKeyJwkRaw` option
- **v0.1.0**: Initial release

## References


- [Performance Analysis]./docs/performance.md (to be created)
- [Architecture Decision Records]./docs/adr/ (to be created)
- [Security Considerations]./docs/security.md (to be created)