Skip to content

Commit 3044fc3

Browse files
committed
feat(): add mtls support
1 parent faba6ab commit 3044fc3

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

src/OpenTelemetry.Exporter.OpenTelemetryProtocol/Implementation/OtlpSpecConfigDefinitions.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,9 @@ internal static class OtlpSpecConfigDefinitions
3131
public const string TracesHeadersEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_HEADERS";
3232
public const string TracesTimeoutEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";
3333
public const string TracesProtocolEnvVarName = "OTEL_EXPORTER_OTLP_TRACES_PROTOCOL";
34+
35+
// mTLS certificate environment variables
36+
public const string CertificateEnvVarName = "OTEL_EXPORTER_OTLP_CERTIFICATE";
37+
public const string ClientKeyEnvVarName = "OTEL_EXPORTER_OTLP_CLIENT_KEY";
38+
public const string ClientCertificateEnvVarName = "OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE";
3439
}

src/OpenTelemetry.Exporter.OpenTelemetryProtocol/OtlpExporterOptions.cs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,5 +311,38 @@ private void ApplyConfiguration(
311311
{
312312
throw new NotSupportedException($"OtlpExporterOptionsConfigurationType '{configurationType}' is not supported.");
313313
}
314+
315+
#if NET8_0_OR_GREATER
316+
// Apply mTLS configuration from environment variables
317+
this.ApplyMtlsConfiguration(configuration);
318+
#endif
319+
}
320+
321+
#if NET8_0_OR_GREATER
322+
private void ApplyMtlsConfiguration(IConfiguration configuration)
323+
{
324+
Debug.Assert(configuration != null, "configuration was null");
325+
326+
// Check and apply CA certificate path from environment variable
327+
if (configuration.TryGetStringValue(OtlpSpecConfigDefinitions.CertificateEnvVarName, out var caCertPath))
328+
{
329+
this.MtlsOptions ??= new OtlpMtlsOptions();
330+
this.MtlsOptions.CaCertificatePath = caCertPath;
331+
}
332+
333+
// Check and apply client certificate path from environment variable
334+
if (configuration.TryGetStringValue(OtlpSpecConfigDefinitions.ClientCertificateEnvVarName, out var clientCertPath))
335+
{
336+
this.MtlsOptions ??= new OtlpMtlsOptions();
337+
this.MtlsOptions.ClientCertificatePath = clientCertPath;
338+
}
339+
340+
// Check and apply client key path from environment variable
341+
if (configuration.TryGetStringValue(OtlpSpecConfigDefinitions.ClientKeyEnvVarName, out var clientKeyPath))
342+
{
343+
this.MtlsOptions ??= new OtlpMtlsOptions();
344+
this.MtlsOptions.ClientKeyPath = clientKeyPath;
345+
}
314346
}
347+
#endif
315348
}

src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,15 @@ or reader
450450
| `OTEL_EXPORTER_OTLP_TIMEOUT` | `TimeoutMilliseconds` |
451451
| `OTEL_EXPORTER_OTLP_PROTOCOL` | `Protocol` (`grpc` or `http/protobuf`)|
452452

453+
The following environment variables can be used to configure mTLS
454+
(mutual TLS) authentication (.NET 8.0+ only):
455+
456+
| Environment variable | `OtlpMtlsOptions` property | Description |
457+
| ---------------------------------------| ------------------------------|---------------------------------------|
458+
| `OTEL_EXPORTER_OTLP_CERTIFICATE` | `CaCertificatePath` | Path to CA certificate file (PEM) |
459+
| `OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE` | `ClientCertificatePath` | Path to client certificate file (PEM)|
460+
| `OTEL_EXPORTER_OTLP_CLIENT_KEY` | `ClientKeyPath` | Path to client private key file (PEM)|
461+
453462
* Logs:
454463

455464
The following environment variables can be used to override the default values

test/OpenTelemetry.Exporter.OpenTelemetryProtocol.Tests/OtlpExporterOptionsTests.cs

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,4 +263,107 @@ public void OtlpExporterOptions_ApplyDefaultsTest()
263263
Assert.NotEqual(defaultOptionsWithData.TimeoutMilliseconds, targetOptionsWithData.TimeoutMilliseconds);
264264
Assert.NotEqual(defaultOptionsWithData.HttpClientFactory, targetOptionsWithData.HttpClientFactory);
265265
}
266+
267+
#if NET8_0_OR_GREATER
268+
[Fact]
269+
public void OtlpExporterOptions_MtlsEnvironmentVariables()
270+
{
271+
// Test CA certificate environment variable
272+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CERTIFICATE", "/path/to/ca.crt");
273+
274+
try
275+
{
276+
var options = new OtlpExporterOptions();
277+
278+
Assert.NotNull(options.MtlsOptions);
279+
Assert.Equal("/path/to/ca.crt", options.MtlsOptions.CaCertificatePath);
280+
}
281+
finally
282+
{
283+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CERTIFICATE", null);
284+
}
285+
}
286+
287+
[Fact]
288+
public void OtlpExporterOptions_MtlsEnvironmentVariables_ClientCertificate()
289+
{
290+
// Test client certificate and key environment variables
291+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE", "/path/to/client.crt");
292+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_KEY", "/path/to/client.key");
293+
294+
try
295+
{
296+
var options = new OtlpExporterOptions();
297+
298+
Assert.NotNull(options.MtlsOptions);
299+
Assert.Equal("/path/to/client.crt", options.MtlsOptions.ClientCertificatePath);
300+
Assert.Equal("/path/to/client.key", options.MtlsOptions.ClientKeyPath);
301+
Assert.True(options.MtlsOptions.IsEnabled);
302+
}
303+
finally
304+
{
305+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE", null);
306+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_KEY", null);
307+
}
308+
}
309+
310+
[Fact]
311+
public void OtlpExporterOptions_MtlsEnvironmentVariables_AllCertificates()
312+
{
313+
// Test all mTLS environment variables together
314+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CERTIFICATE", "/path/to/ca.crt");
315+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE", "/path/to/client.crt");
316+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_KEY", "/path/to/client.key");
317+
318+
try
319+
{
320+
var options = new OtlpExporterOptions();
321+
322+
Assert.NotNull(options.MtlsOptions);
323+
Assert.Equal("/path/to/ca.crt", options.MtlsOptions.CaCertificatePath);
324+
Assert.Equal("/path/to/client.crt", options.MtlsOptions.ClientCertificatePath);
325+
Assert.Equal("/path/to/client.key", options.MtlsOptions.ClientKeyPath);
326+
Assert.True(options.MtlsOptions.IsEnabled);
327+
}
328+
finally
329+
{
330+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CERTIFICATE", null);
331+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE", null);
332+
Environment.SetEnvironmentVariable("OTEL_EXPORTER_OTLP_CLIENT_KEY", null);
333+
}
334+
}
335+
336+
[Fact]
337+
public void OtlpExporterOptions_MtlsEnvironmentVariables_NoEnvironmentVariables()
338+
{
339+
// Ensure no mTLS options are set when no environment variables are present
340+
var options = new OtlpExporterOptions();
341+
342+
Assert.Null(options.MtlsOptions);
343+
}
344+
345+
[Fact]
346+
public void OtlpExporterOptions_MtlsEnvironmentVariables_UsingIConfiguration()
347+
{
348+
// Test using IConfiguration instead of environment variables
349+
var values = new Dictionary<string, string?>
350+
{
351+
["OTEL_EXPORTER_OTLP_CERTIFICATE"] = "/config/path/to/ca.crt",
352+
["OTEL_EXPORTER_OTLP_CLIENT_CERTIFICATE"] = "/config/path/to/client.crt",
353+
["OTEL_EXPORTER_OTLP_CLIENT_KEY"] = "/config/path/to/client.key",
354+
};
355+
356+
var configuration = new ConfigurationBuilder()
357+
.AddInMemoryCollection(values)
358+
.Build();
359+
360+
var options = new OtlpExporterOptions(configuration, OtlpExporterOptionsConfigurationType.Default, new());
361+
362+
Assert.NotNull(options.MtlsOptions);
363+
Assert.Equal("/config/path/to/ca.crt", options.MtlsOptions.CaCertificatePath);
364+
Assert.Equal("/config/path/to/client.crt", options.MtlsOptions.ClientCertificatePath);
365+
Assert.Equal("/config/path/to/client.key", options.MtlsOptions.ClientKeyPath);
366+
Assert.True(options.MtlsOptions.IsEnabled);
367+
}
368+
#endif
266369
}

0 commit comments

Comments
 (0)