Reference

Crypto Provider

acton-service uses rustls for all TLS — the HTTPS listener, the reqwest HTTP client, the sqlx Postgres connector, and the tonic gRPC stack. Since rustls 0.23, the cryptographic primitives have been pluggable via the CryptoProvider trait. The framework ships with two providers and picks one at compile time.


Default: aws-lc-rs

crypto-aws-lc-rs is enabled by default. It uses aws-lc-rs, AWS's Rust bindings to AWS-LC, which is a fork of BoringSSL maintained for AWS production use.

It is the default because:

  • FIPS 140-3 capable. aws-lc-rs exposes a fips feature that links the FIPS 140-3 validated AWS-LC module. ring has no FIPS validation. For FedRAMP, FISMA, or DoD workloads, this is the only viable path.
  • Ecosystem-aligned. rustls 0.23+, tonic 0.14+, and sqlx 0.8+ all prefer aws-lc-rs when both providers are available.
  • Faster on server hardware. AWS's tuned AES-GCM and ChaCha20 assembly outperforms ring by roughly 1.5–2× on x86_64 with AES-NI — a measurable win on a TLS-terminating service.
  • Maintained continuously. A full-time AWS team funds AWS-LC with continuous fuzzing and audits.

Opt-in: ring

crypto-ring is available for environments where the C/CMake toolchain that aws-lc-rs requires at build time is impractical — minimal Alpine images, some cross-compilation targets, or build pipelines that cannot install a C compiler.

Enable it explicitly:

[dependencies]
acton-service = { version = "

Mutual exclusivity

Exactly one of crypto-aws-lc-rs or crypto-ring must be enabled. The framework guards the invariant with a compile_error!:

error: Features `crypto-aws-lc-rs` and `crypto-ring` are mutually exclusive.
       Enable exactly one rustls crypto provider.

If you disable default features without selecting a provider, you'll see:

error: A rustls crypto provider is required.
       Enable `crypto-aws-lc-rs` (default) or `crypto-ring`.

Bootstrapping at runtime

rustls 0.23+ panics on ServerConfig::builder() or ClientConfig::builder() when more than one provider is compiled into the binary and no default is installed — which happens routinely because dependencies such as quinn-proto and jsonwebtoken link aws-lc-rs transitively regardless of your choice.

acton-service installs the chosen provider automatically before the TLS listener starts. If your binary uses reqwest, sqlx, or tonic TLS clients without mounting the framework's TLS listener, call the bootstrap once from main:

use acton_service::crypto::ensure_default_crypto_provider;

#[tokio::main]
async fn main() -> Result<()> {
    ensure_default_crypto_provider();
    // ... your service setup ...
    Ok(())
}

The call is idempotent — repeat calls are no-ops.

FIPS 140-3

To use the FIPS-validated AWS-LC module, build with the aws-lc-rs crate's fips feature enabled in your downstream binary. See the aws-lc-rs FIPS documentation for build prerequisites (FIPS-validated module package and a supported host triple). acton-service does not gate this behind its own feature; it simply delegates to whichever build of aws-lc-rs Cargo resolves.

A note on cargo tree

crypto-ring builds will still show aws-lc-rs in cargo tree because quinn-proto (pulled in by reqwest's HTTP/3 path) and jsonwebtoken's rust_crypto feature link it unconditionally. The installed provider — the one rustls actually uses for handshakes and encryption — is whichever feature you enabled, not whatever happens to be in the binary.

Previous
Feature Flags