@@ -231,7 +231,9 @@ impl TonicExporterBuilder {
231231
232232 let compression = self . resolve_compression ( signal_compression_var) ?;
233233
234- let ( headers_from_env, headers_for_logging) = parse_headers_from_env ( signal_headers_var) ;
234+ let ( headers_from_env, all_headers) = parse_headers_from_env ( signal_headers_var) ;
235+ let headers_for_logging = redact_sensitive_headers ( all_headers) ;
236+
235237 let metadata = merge_metadata_with_headers_from_env (
236238 self . tonic_config . metadata . unwrap_or_default ( ) ,
237239 headers_from_env,
@@ -608,6 +610,25 @@ fn parse_headers_from_env(signal_headers_var: &str) -> (HeaderMap, Vec<(String,
608610 )
609611}
610612
613+ fn redact_sensitive_headers ( headers : Vec < ( String , String ) > ) -> Vec < ( String , String ) > {
614+ headers
615+ . iter ( )
616+ . map ( |( k, v) | {
617+ let header_name = k. to_lowercase ( ) ;
618+ let value = v. to_lowercase ( ) ;
619+ if header_name. contains ( "auth" )
620+ || header_name. contains ( "api-key" )
621+ || header_name. contains ( "token" )
622+ || value. contains ( "bearer" )
623+ {
624+ ( k. clone ( ) , "[REDACTED]" . to_string ( ) )
625+ } else {
626+ ( k. clone ( ) , v. clone ( ) )
627+ }
628+ } )
629+ . collect ( )
630+ }
631+
611632/// Expose interface for modifying [TonicConfig] fields within the exporter builders.
612633pub ( crate ) trait HasTonicConfig {
613634 /// Return a mutable reference to the export config within the exporter builders.
@@ -807,7 +828,7 @@ impl<B: HasTonicConfig> WithTonicConfig for B {
807828#[ cfg( test) ]
808829mod tests {
809830 use crate :: exporter:: tests:: run_env_test;
810- use crate :: exporter:: tonic:: WithTonicConfig ;
831+ use crate :: exporter:: tonic:: { redact_sensitive_headers , WithTonicConfig } ;
811832 #[ cfg( feature = "grpc-tonic" ) ]
812833 use crate :: exporter:: Compression ;
813834 use crate :: { TonicExporterBuilder , OTEL_EXPORTER_OTLP_TRACES_ENDPOINT } ;
@@ -981,6 +1002,24 @@ mod tests {
9811002 ) ;
9821003 }
9831004
1005+ #[ test]
1006+ fn test_sensitive_headers_redacted ( ) {
1007+ run_env_test (
1008+ vec ! [ (
1009+ OTEL_EXPORTER_OTLP_HEADERS ,
1010+ "authorization=Bearer my-secret-token" ,
1011+ ) ] ,
1012+ || {
1013+ let headers_from_env = super :: parse_headers_from_env ( OTEL_EXPORTER_OTLP_HEADERS ) ;
1014+ let redacted = redact_sensitive_headers ( headers_from_env. 1 ) ;
1015+
1016+ let ( _, header_value) =
1017+ redacted. iter ( ) . find ( |( k, _) | k == "authorization" ) . unwrap ( ) ;
1018+ assert_eq ! ( * header_value, "[REDACTED]" . to_string( ) )
1019+ } ,
1020+ ) ;
1021+ }
1022+
9841023 #[ test]
9851024 fn test_priority_of_signal_env_over_generic_env_for_endpoint ( ) {
9861025 run_env_test (
0 commit comments