Skip to content

Commit febe718

Browse files
authored
feat(OTLP): add tls-ring, tls-aws-lc, and tls-provider-agnostic feature flags [patch release v0.31.1] (#3426)
1 parent 285dc92 commit febe718

4 files changed

Lines changed: 100 additions & 10 deletions

File tree

opentelemetry-otlp/CHANGELOG.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,44 @@
22

33
## vNext
44

5+
## 0.31.1
6+
7+
Released 2026-Mar-18
8+
9+
- Add `tls-ring` and `tls-aws-lc` feature flags for explicit crypto provider selection.
10+
- Add `tls-provider-agnostic` feature flag for environments that require a custom crypto backend (e.g., OpenSSL for FIPS compliance). Enables TLS code paths without bundling `ring` or `aws-lc-rs`.
11+
12+
### Feature combination guidance
13+
14+
The new TLS features should be used **individually** — do not combine multiple
15+
crypto provider features. The existing `tls-roots` and `tls-webpki-roots`
16+
features implicitly enable `tls` (which pulls in `ring`), so combining them
17+
with `tls-aws-lc` or `tls-provider-agnostic` will compile both providers and
18+
may cause unexpected behavior.
19+
20+
**Recommended usage:**
21+
22+
| Goal | Features to enable |
23+
|---|---|
24+
| TLS with ring + system roots | `tls-ring`, `tls-roots` |
25+
| TLS with ring + Mozilla roots | `tls-ring`, `tls-webpki-roots` |
26+
| TLS with aws-lc + custom CA | `tls-aws-lc` (provide CA via `ClientTlsConfig`) |
27+
| TLS with custom provider (e.g., FIPS) | `tls-provider-agnostic` (call `CryptoProvider::install_default()` in your app) |
28+
29+
**Avoid these combinations:**
30+
31+
| Combination | Problem |
32+
|---|---|
33+
| `tls-aws-lc` + `tls-roots` | Pulls in `ring` via `tls-roots``tls`; both providers compiled, which can cause runtime panics or unpredictable provider selection |
34+
| `tls-aws-lc` + `tls-webpki-roots` | Same issue — both providers compiled, which can cause runtime panics or unpredictable provider selection |
35+
| `tls-provider-agnostic` + `tls-roots` | Defeats the purpose — bundles ring, which can cause runtime panics or unpredictable provider selection |
36+
| `tls-provider-agnostic` + `tls-webpki-roots` | Same issue — bundles ring, which can cause runtime panics or unpredictable provider selection |
37+
| `tls-ring` + `tls-aws-lc` | Both providers compiled, which can cause runtime panics or unpredictable provider selection |
38+
39+
> **Note:** If you need root certificates with `tls-aws-lc`, depend on
40+
> `tonic/tls-native-roots` or `tonic/tls-webpki-roots` directly in your own
41+
> `Cargo.toml` instead of using `tls-roots`/`tls-webpki-roots` from this crate.
42+
543
## 0.31.0
644

745
Released 2025-Sep-25

opentelemetry-otlp/Cargo.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "opentelemetry-otlp"
3-
version = "0.31.0"
3+
version = "0.31.1"
44
description = "Exporter for the OpenTelemetry Collector"
55
homepage = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-otlp"
66
repository = "https://github.com/open-telemetry/opentelemetry-rust/tree/main/opentelemetry-otlp"
@@ -77,6 +77,12 @@ zstd-tonic = ["tonic/zstd"]
7777
gzip-http = ["flate2"]
7878
zstd-http = ["zstd"]
7979
tls = ["tonic/tls-ring"]
80+
tls-ring = ["tonic/tls-ring"]
81+
tls-aws-lc = ["tonic/tls-aws-lc"]
82+
# Provider-agnostic TLS: enables TLS code paths without bundling a specific
83+
# crypto provider. Use this when you install a
84+
# CryptoProvider globally (e.g., via rustls-openssl for FIPS/OpenSSL environments).
85+
tls-provider-agnostic = ["tonic/_tls-any"]
8086
tls-roots = ["tls", "tonic/tls-native-roots"]
8187
tls-webpki-roots = ["tls", "tonic/tls-webpki-roots"]
8288

opentelemetry-otlp/src/exporter/tonic/mod.rs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ use tonic::codec::CompressionEncoding;
88
use tonic::metadata::{KeyAndValueRef, MetadataMap};
99
use tonic::service::Interceptor;
1010
use tonic::transport::Channel;
11-
#[cfg(feature = "tls")]
11+
#[cfg(any(
12+
feature = "tls",
13+
feature = "tls-ring",
14+
feature = "tls-aws-lc",
15+
feature = "tls-provider-agnostic"
16+
))]
1217
use tonic::transport::ClientTlsConfig;
1318

1419
use super::{default_headers, parse_header_string, OTEL_EXPORTER_OTLP_GRPC_ENDPOINT_DEFAULT};
@@ -34,7 +39,12 @@ pub struct TonicConfig {
3439
/// Custom metadata entries to send to the collector.
3540
pub(crate) metadata: Option<MetadataMap>,
3641
/// TLS settings for the collector endpoint.
37-
#[cfg(feature = "tls")]
42+
#[cfg(any(
43+
feature = "tls",
44+
feature = "tls-ring",
45+
feature = "tls-aws-lc",
46+
feature = "tls-provider-agnostic"
47+
))]
3848
pub(crate) tls_config: Option<ClientTlsConfig>,
3949
/// The compression algorithm to use when communicating with the collector.
4050
pub(crate) compression: Option<Compression>,
@@ -69,7 +79,7 @@ impl TryFrom<Compression> for tonic::codec::CompressionEncoding {
6979
///
7080
/// It allows you to
7181
/// - add additional metadata
72-
/// - set tls config (via the `tls` feature)
82+
/// - set tls config (via the `tls`, `tls-ring`, `tls-aws-lc`, or `tls-provider-agnostic` features)
7383
/// - specify custom [channel]s
7484
///
7585
/// [tonic]: <https://github.com/hyperium/tonic>
@@ -127,7 +137,12 @@ impl Default for TonicExporterBuilder {
127137
.try_into()
128138
.expect("Invalid tonic headers"),
129139
)),
130-
#[cfg(feature = "tls")]
140+
#[cfg(any(
141+
feature = "tls",
142+
feature = "tls-ring",
143+
feature = "tls-aws-lc",
144+
feature = "tls-provider-agnostic"
145+
))]
131146
tls_config: None,
132147
compression: None,
133148
channel: Option::default(),
@@ -197,7 +212,12 @@ impl TonicExporterBuilder {
197212
.map_err(|op| ExporterBuildError::InvalidUri(endpoint_clone.clone(), op.to_string()))?;
198213
let timeout = resolve_timeout(signal_timeout_var, config.timeout.as_ref());
199214

200-
#[cfg(feature = "tls")]
215+
#[cfg(any(
216+
feature = "tls",
217+
feature = "tls-ring",
218+
feature = "tls-aws-lc",
219+
feature = "tls-provider-agnostic"
220+
))]
201221
let channel = match self.tonic_config.tls_config {
202222
Some(tls_config) => endpoint
203223
.tls_config(tls_config)
@@ -207,7 +227,12 @@ impl TonicExporterBuilder {
207227
.timeout(timeout)
208228
.connect_lazy();
209229

210-
#[cfg(not(feature = "tls"))]
230+
#[cfg(not(any(
231+
feature = "tls",
232+
feature = "tls-ring",
233+
feature = "tls-aws-lc",
234+
feature = "tls-provider-agnostic"
235+
)))]
211236
let channel = endpoint.timeout(timeout).connect_lazy();
212237

213238
otel_debug!(name: "TonicChannelBuilt", endpoint = endpoint_clone, timeout_in_millisecs = timeout.as_millis(), compression = format!("{:?}", compression), headers = format!("{:?}", headers_for_logging));
@@ -369,7 +394,12 @@ impl HasTonicConfig for TonicExporterBuilder {
369394
/// ```
370395
pub trait WithTonicConfig {
371396
/// Set the TLS settings for the collector endpoint.
372-
#[cfg(feature = "tls")]
397+
#[cfg(any(
398+
feature = "tls",
399+
feature = "tls-ring",
400+
feature = "tls-aws-lc",
401+
feature = "tls-provider-agnostic"
402+
))]
373403
fn with_tls_config(self, tls_config: ClientTlsConfig) -> Self;
374404

375405
/// Set custom metadata entries to send to the collector.
@@ -478,7 +508,12 @@ pub trait WithTonicConfig {
478508
}
479509

480510
impl<B: HasTonicConfig> WithTonicConfig for B {
481-
#[cfg(feature = "tls")]
511+
#[cfg(any(
512+
feature = "tls",
513+
feature = "tls-ring",
514+
feature = "tls-aws-lc",
515+
feature = "tls-provider-agnostic"
516+
))]
482517
fn with_tls_config(mut self, tls_config: ClientTlsConfig) -> Self {
483518
self.tonic_config().tls_config = Some(tls_config);
484519
self

opentelemetry-otlp/src/lib.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,12 @@
221221
//! * `grpc-tonic`: Use `tonic` as grpc layer.
222222
//! * `gzip-tonic`: Use gzip compression for `tonic` grpc layer.
223223
//! * `zstd-tonic`: Use zstd compression for `tonic` grpc layer.
224+
//! * `tls`: Enable rustls TLS support using ring for `tonic` (default TLS feature).
225+
//! * `tls-ring`: Enable rustls TLS support using ring for `tonic`.
226+
//! * `tls-aws-lc`: Enable rustls TLS support using aws-lc for `tonic`.
227+
//! * `tls-provider-agnostic`: Provider-agnostic TLS — enables TLS code paths without bundling a specific
228+
//! crypto provider. Use this when you install a `CryptoProvider` globally
229+
//! (e.g., via `rustls-openssl` for FIPS/OpenSSL environments).
224230
//! * `tls-roots`: Adds system trust roots to rustls-based gRPC clients using the rustls-native-certs crate
225231
//! * `tls-webpki-roots`: Embeds Mozilla's trust roots to rustls-based gRPC clients using the webpki-roots crate
226232
//!
@@ -462,7 +468,12 @@ pub mod tonic_types {
462468
}
463469

464470
/// Re-exported types from `tonic::transport`.
465-
#[cfg(feature = "tls")]
471+
#[cfg(any(
472+
feature = "tls",
473+
feature = "tls-ring",
474+
feature = "tls-aws-lc",
475+
feature = "tls-provider-agnostic"
476+
))]
466477
pub mod transport {
467478
#[doc(no_inline)]
468479
pub use tonic::transport::{Certificate, ClientTlsConfig, Identity};

0 commit comments

Comments
 (0)