# authia
High-performance JWT verification library for Ed25519 using WebAssembly.
## Features
- 🚀 Fast Ed25519 JWT verification using Rust + WebAssembly
- ⚡ **v0.3.0 Optimization**: Single-pass JSON parsing for maximum performance
- 🔒 Secure by design - algorithm fixed to Ed25519
- 🌐 Universal runtime support (Node.js, Browser, Cloudflare Workers)
- 📦 Zero runtime dependencies
- 🎯 TypeScript type definitions included
- ⚡ Automatic Wasm initialization
## 📊 Benchmarks
Performance varies significantly by runtime environment:
**Cloudflare Workers / Edge Runtimes:**
| **authia (WASM)** | **0.20ms** | **0.17ms** | **0.36ms** |
| jose (WebCrypto) | 0.30ms | 0.28ms | 0.50ms |
**Node.js (native crypto):**
| jose (native) | **0.01-0.03ms** ⚡ |
| authia (WASM) | 0.17-0.20ms |
_In Node.js, jose uses native C++ crypto bindings and is significantly faster. authia is optimized for edge runtimes where both libraries use similar APIs._
## Installation
```bash
npm install authia
```
## Usage
The library automatically detects the environment (Node.js or Bundler/Workers) and handles WebAssembly loading.
### Access Token Verification
```typescript
import { verifyAccessToken } from "authia";
try {
// ⚡ RECOMMENDED: Use publicKeyJwkRaw for better performance (v0.2.0+)
const payload = await verifyAccessToken(token, {
publicKeyJwkRaw: process.env.JWT_PUBLIC_KEY, // Raw JWK JSON string
audience: "kapock-app",
issuer: "https://auth.kapock.com",
});
console.log(`User ID: ${payload.sub}, Email: ${payload.email}`);
} catch (error) {
console.error("Token verification failed:", error);
}
```
**Legacy (still supported, but slower):**
```typescript
// Base64-encoded JWK (backward compatible)
const payload = await verifyAccessToken(token, {
publicKeyJwk: btoa(process.env.JWT_PUBLIC_KEY), // Requires base64 encoding
audience: "kapock-app",
issuer: "https://auth.kapock.com",
});
```
### Refresh Token Verification
```typescript
import { verifyRefreshToken } from "authia";
const payload = await verifyRefreshToken(token, {
publicKeyJwkRaw: process.env.JWT_PUBLIC_KEY, // Use raw JWK for better performance
audience: "kapock-app",
issuer: "https://auth.kapock.com",
});
console.log(`JTI: ${payload.jti}`);
```
### Performance Tips
1. **Use `publicKeyJwkRaw`** instead of `publicKeyJwk` (2-5x faster in high-throughput scenarios)
2. **Cache your verification options** at the worker/process level
3. The library automatically caches the decoded public key internally
```typescript
// Worker-level caching example (Cloudflare Workers)
export async function verifyToken(token: string, env: Env) {
if (!cachedPublicKey) {
cachedPublicKey = env.JWT_PUBLIC_KEY.trim();
}
return verifyAccessToken(token, {
publicKeyJwkRaw: cachedPublicKey, // Avoid repeated trim() calls
audience: "kapock-app",
issuer: "https://auth.kapock.com",
});
}
```
## Runtime Behavior
### Node.js
Verification is **synchronous**. The WebAssembly module is loaded and instantiated at startup using the optimized Node.js target.
### Cloudflare Workers / Bundlers
Verification is also **synchronous**. The library automatically handles WebAssembly instantiation during module load. The `await` in examples is supported but not strictly required for the verification itself (it returns the payload directly).
## API
See [API Documentation](./docs/api.md) for detailed information.
## Known Issues & Limitations
⚠️ **Important Notes for Production Use**
### Performance Considerations
**Node.js Environments:**
- authia has a **JS ↔ WASM boundary overhead** of ~0.1-0.15ms per call
- The popular `jose` library uses native C++ crypto bindings and is typically **faster in Node.js** (0.01-0.03ms)
- **Recommendation**: For Node.js backends, consider using `jose` instead of authia
**Cloudflare Workers / Edge Runtimes:**
- authia performs **competitively** in these environments where `jose` also uses WebCrypto APIs
- The WASM approach provides **consistent performance** across different edge platforms
- **Recommendation**: authia is well-suited for Cloudflare Workers with Ed25519 tokens
### Schema Validation (v0.3.x)
- **Strict schema validation**: v0.3.1-v0.3.3 use strict type checking for JWT claims
- Missing optional fields (like `email`) may cause verification to fail
- **Workaround**: Ensure all tokens include expected fields, or use v0.2.x for more lenient parsing
- **Future improvement**: Planned migration to flexible schema with `Option<T>` types
### Environment Variable Parsing
- Public key format detection: The library attempts to auto-detect JSON vs Base64-encoded JWK
- **Best practice**: Use raw JSON format for `publicKeyJwkRaw` option (recommended)
- If using Base64, ensure proper encoding without PEM headers
### Recommended Use Cases
✅ **Good fit:**
- Cloudflare Workers with Ed25519 JWT tokens
- Edge runtimes requiring consistent cross-platform behavior
- Learning Rust + WebAssembly development
❌ **Consider alternatives:**
- Node.js backends with high-throughput requirements → use `jose`
- Tokens with varying claim structures → use v0.2.x or `jose`
- Production systems requiring maximum stability → use `jose`
## License
MIT