TLS with rustls
Terminate and originate TLS in Rust with rustls - pure-Rust TLS using aws-lc-rs or ring crypto backends.
Search across all documentation pages
Terminate and originate TLS in Rust with rustls - pure-Rust TLS using aws-lc-rs or ring crypto backends.
Quick-reference recipe card - copy-paste ready.
[dependencies]
reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "json"] }
rustls = "0.23"
tokio-rustls = "0.26"let client = reqwest::Client::builder()
.use_rustls_tls()
.build()?;When to reach for this: HTTPS clients and servers without OpenSSL dependency - common in Rust microservices and static binaries.
use rustls::pki_types::{CertificateDer, PrivateKeyDer};
use std::sync::Arc;
fn load_certs(pem: &str) -> Vec<CertificateDer<'static>> {
rustls_pemfile::certs(&mut pem.as_bytes())
.map(|r| r.unwrap())
.collect()
}
fn load_key(pem: &str) -> PrivateKeyDer<'static> {
rustls_pemfile::private_key(&mut pem.as_bytes())
.next()
.unwrap()
.unwrap()
}
fn rustls_server_config(cert_pem: &str, key_pem: &str) -> Arc<rustls::ServerConfig> {
let certs = load_certs(cert_pem);
let key = load_key(key_pem);
let config = rustls::ServerConfig::builder()
.with_no_client_auth()
.with_single_cert(certs, key)
.unwrap();
Arc::new(config)
}What this demonstrates:
rustls-pemfile.ServerConfig::builder() with certificate chain and private key.Arc config shared across connections.webpki-roots or platform verifier crates.| Pattern | Where TLS runs |
|---|---|
| Edge termination | Load balancer (common) |
| Sidecar | Envoy/mTLS mesh |
| In-process | rustls on Axum (less common) |
// mTLS client trusts custom CA
let mut roots = rustls::RootCertStore::empty();
roots.add(ca_cert).unwrap();
let config = rustls::ClientConfig::builder()
.with_root_certificates(roots)
.with_client_auth_cert(client_certs, client_key)?;danger_accept_invalid_certs in prod. Fix: Proper root store and hostname verification.| Alternative | Use When | Don't Use When |
|---|---|---|
| OpenSSL (native-tls) | Legacy enterprise CA tooling | Avoiding OpenSSL dep is goal |
| External termination | Kubernetes ingress | End-to-end encryption required inside VPC |
mesalink | OpenSSL compatibility layer | Greenfield rustls |
Enable rustls-tls feature explicitly in Cargo.toml.
Often TLS at ingress; axum-server or hyper rustls for direct HTTPS.
Reload config on SIGHUP or restart pods with new secret volume.
Custom root CA added to RootCertStore.
HTTP/2 negotiated via ALPN in rustls config for gRPC.
aws-lc-rs FIPS module where compliance requires.
RUSTLS_LOG=debug - never in prod with secrets.
Local mkcert or dev-only custom root - never ship to prod.
rustls competitive with OpenSSL; session resumption helps latency.
Server::builder().tls_config(...)? with identity from rustls.
Stack versions: This page was written for Rust 1.97.0 (edition 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, and Polars 0.46+.
Reviewed by Chris St. John·Last updated Jul 16, 2026