Skip to content

[geneva-uploader] Add optional rustls TLS backend (FIPS / OpenSSL-free deployments) #631

@thperapp

Description

@thperapp

Problem

The Geneva uploader (geneva-uploader, and by extension opentelemetry-exporter-geneva and geneva-uploader-ffi) hard-codes native-tls as its TLS backend.
This means every consumer of this library transitively pulls in an OpenSSL (or SChannel / Secure Transport) runtime dependency and uses it for both:

  1. The TLS transport to the Geneva Config Service / Ingestion Gateway, and
  2. Parsing the PKCS#12 client certificate used for mTLS auth.

Why this is a problem

  • FIPS / regulated deployments. Consumers that need FIPS-validated cryptography (for example, the Linux Geneva agent which ships rustls-symcrypt) cannot route Geneva's TLS through their chosen rustls::crypto::CryptoProvider. They are stuck linking OpenSSL solely to satisfy the Geneva uploader, even though the rest of their stack is OpenSSL-free.
  • OpenSSL-free / minimal-image builds. Containers and embedded targets that would otherwise be pure-Rust must still ship and patch an OpenSSL runtime just for this one crate, increasing binary size, attack surface, and CVE-tracking overhead.
  • Ecosystem alignment. reqwest and most of the modern Rust HTTP ecosystem support both backends as additive features.

Proposal

Add an optional tls-rustls Cargo feature alongside the existing default tls-native feature, in all three crates:

  • geneva-uploader (the actual backend implementation)
  • opentelemetry-exporter-geneva (forwarded flag)
  • geneva-uploader-ffi (forwarded flag)

Requirements:

  • tls-native remains the default so existing builds are bit-for-bit unchanged.
  • The two features are additive (so cargo build --all-features and cargo hack style matrices keep working). If both are enabled, tls-rustls takes precedence at runtime.
  • The rustls backend honors any rustls::crypto::CryptoProvider that the host process installed at startup (e.g. rustls_symcrypt::default_symcrypt_provider().install_default()), and falls back to the bundled provider otherwise.
  • TLS 1.2 pinning and system-trust-store behavior are preserved across both backends (Geneva requires TLS 1.2).
  • PKCS#12 client-cert parsing for the rustls path uses a pure-Rust crate (e.g. p12-keystore) so the rustls build path has no OpenSSL dependency at all.

Example usage

[dependencies]
opentelemetry-exporter-geneva = { version = "*", default-features = false, features = ["tls-rustls"] }
// Once, at process startup, before constructing the exporter:
rustls_symcrypt::default_symcrypt_provider()
    .install_default()
    .expect("failed to install SymCrypt CryptoProvider");

Scope

  • Add tls-native (default) and tls-rustls features to geneva-uploader.
  • Implement a rustls-based HTTPS + mTLS path in config_service/client.rs using rustls + rustls-native-certs + p12-keystore.
  • Forward the feature flags from opentelemetry-exporter-geneva and geneva-uploader-ffi.
  • Document the backends, the CryptoProvider extension point, and the additive-feature precedence rule in the crate READMEs and CHANGELOGs.

working branch - thperapp/geneva-uploader-rustls.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions