JWT tokens, bcrypt passwords, API keys, and auth middleware.
Production-ready authentication in a few function calls. Built on jsonwebtoken and bcrypt Rust crates with secure defaults (HS256, cost factor 12).
Every function in the std.auth module.
Hashes a plaintext password using bcrypt with cost factor 12. Returns the hash string including the embedded salt. Each call produces a different hash for the same input.
hash := auth.hash_password("secret123")
// Returns: "$2b$12$LJ3m4ys3Lg..." (60 chars, includes salt)
Compares a plaintext password against a bcrypt hash. Returns true if they match. Constant-time comparison prevents timing attacks.
valid := auth.verify_password("secret123", stored_hash)
// Returns: true or false
Creates a signed JWT token from a JSON claims string and a secret key. Uses HS256 algorithm. Claims should include sub (subject) and optionally exp (expiration), role, etc.
token := auth.jwt_sign("{\"sub\":\"alice\",\"role\":\"admin\"}", "my-secret")
// Returns: "eyJhbGciOiJIUzI1NiJ9.eyJzdWI..." (compact JWT)
Verifies a JWT token's signature and returns the decoded claims as a JSON string. Throws an error if the token is invalid, expired, or tampered with.
claims := auth.jwt_verify(token, "my-secret")
// Returns: "{\"sub\":\"alice\",\"role\":\"admin\"}"
Validates the X-API-Key header against an expected value. Returns true if they match. Use for machine-to-machine authentication (webhooks, service calls).
valid := auth.api_key(req, "my-service-key-2026")
// Checks: req.headers["X-API-Key"] == "my-service-key-2026"
Wraps a route handler with JWT authentication. Extracts the Bearer token from the Authorization header, verifies it, and passes decoded claims to the handler. Returns 401 if invalid.
// Protected route — only accessible with valid JWT
server.get("/admin") => auth.middleware(fn(req) -> Response {
Response.json({ message: "Welcome, admin" })
})
Full auth flow: register → login → access protected routes.
module main
use std.http
use std.auth
use std.env
fn main() {
env.load_dotenv()
jwt_secret := env.require("JWT_SECRET")
server := http.new(port: 8080)
// Register — hash password with bcrypt
server.post("/register") => fn(req) -> Response {
hash := auth.hash_password(req.body.password)
Response.json({ hash: hash, message: "Registered" })
}
// Login — issue JWT token
server.post("/login") => fn(req) -> Response {
claims := "{\"sub\":\"alice\",\"role\":\"admin\"}"
token := auth.jwt_sign(claims, "my_jwt_secret_key")
Response.json({ token: token })
}
// Protected route — JWT middleware
server.get("/profile") => auth.middleware(fn(req) -> Response {
Response.json({ user: "authenticated" })
})
// API key endpoint
server.get("/api/data") => fn(req) -> Response {
valid := auth.api_key(req, "my-service-key")
Response.json({ data: "sensitive" })
}
server.start()
}
What the compiler produces for authentication operations.
Transpiled Output (simplified)use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};
use bcrypt::{hash, verify, DEFAULT_COST};
// auth.hash_password("secret123")
let hashed = hash("secret123", 12).unwrap();
// auth.verify_password("secret123", stored_hash)
let valid = verify("secret123", &stored_hash).unwrap();
// auth.jwt_sign(claims, "my-secret")
let token = encode(
&Header::default(),
&claims,
&EncodingKey::from_secret("my-secret".as_ref())
).unwrap();
// auth.jwt_verify(token, "my-secret")
let decoded = decode::<Claims>(
&token,
&DecodingKey::from_secret("my-secret".as_ref()),
&Validation::default()
).unwrap();
// auth.middleware(handler)
// Generates an Axum middleware extractor that:
// 1. Reads Authorization: Bearer <token> header
// 2. Verifies JWT signature
// 3. Returns 401 if invalid
// 4. Injects claims into request extensions