<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Network options on Grafana Labs</title><link>https://grafana.com/docs/tempo/v3.0.x/configuration/network/</link><description>Recent content in Network options on Grafana Labs</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="/docs/tempo/v3.0.x/configuration/network/index.xml" rel="self" type="application/rss+xml"/><item><title>Configure IPv6</title><link>https://grafana.com/docs/tempo/v3.0.x/configuration/network/ipv6/</link><pubDate>Thu, 28 May 2026 17:50:33 +0100</pubDate><guid>https://grafana.com/docs/tempo/v3.0.x/configuration/network/ipv6/</guid><content><![CDATA[&lt;h1 id=&#34;configure-ipv6&#34;&gt;Configure IPv6&lt;/h1&gt;
&lt;p&gt;Tempo can be configured to communicate between the components using Internet Protocol Version 6, or IPv6.&lt;/p&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The underlying infrastructure must support this address family. This configuration may be used in a single-stack IPv6 environment, or in a dual-stack environment where both IPv6 and IPv4 are present. In a dual-stack scenario, only one address family may be configured at a time, and all components must be configured for that address family.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;protocol-configuration&#34;&gt;Protocol configuration&lt;/h2&gt;
&lt;p&gt;This sample listen configuration will allow the gRPC and HTTP servers to listen on IPv6, and configure the various memberlist components to enable IPv6.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;memberlist:
  bind_addr:
    - &amp;#39;::&amp;#39;
  bind_port: 7946

# Required only when using the global ingestion rate strategy.
distributor:
  ring:
    enable_inet6: true

# Only needed if the backend-worker ring is enabled (kvstore.store is set).
backend_worker:
  ring:
    enable_inet6: true

metrics_generator:
  ring:
    enable_inet6: true

live_store:
  ring:
    enable_inet6: true

server:
  grpc_listen_address: &amp;#39;::0&amp;#39;
  grpc_listen_port: 9095
  http_listen_address: &amp;#39;::0&amp;#39;
  http_listen_port: 3200&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The &lt;code&gt;live_store.partition_ring&lt;/code&gt; doesn&amp;rsquo;t expose &lt;code&gt;enable_inet6&lt;/code&gt;. It inherits its address family from the top-level &lt;code&gt;memberlist&lt;/code&gt; configuration.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;kubernetes-service-configuration&#34;&gt;Kubernetes service configuration&lt;/h2&gt;
&lt;p&gt;Each service fronting the workloads needs to be configured with &lt;code&gt;spec.ipFamilies&lt;/code&gt; and &lt;code&gt;spec.ipFamilyPolicy&lt;/code&gt; set. Refer to this &lt;code&gt;backend-worker&lt;/code&gt; example:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: Service
metadata:
  labels:
    name: backend-worker
  name: backend-worker
  namespace: tracing
spec:
  clusterIP: fccb::31a7
  clusterIPs:
    - fccb::31a7
  internalTrafficPolicy: Cluster
  ipFamilies:
    - IPv6
  ipFamilyPolicy: SingleStack
  ports:
    - name: backend-worker-http-metrics
      port: 3200
      protocol: TCP
      targetPort: 3200
  selector:
    app: backend-worker
    name: backend-worker
  sessionAffinity: None
  type: ClusterIP&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In addition to the per-component services, Tempo components discover each other through a separate headless &lt;code&gt;gossip-ring&lt;/code&gt; Service that exposes the memberlist port. Configure it as IPv6 so that components can join the cluster over IPv6.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: Service
metadata:
  name: gossip-ring
  namespace: tracing
spec:
  clusterIP: None
  ipFamilies:
    - IPv6
  ipFamilyPolicy: SingleStack
  ports:
    - name: gossip-ring
      port: 7946
      protocol: TCP
      targetPort: 7946
  selector:
    tempo-gossip-member: &amp;#34;true&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Each Tempo component then joins &lt;code&gt;memberlist&lt;/code&gt; by referencing the headless Service&amp;rsquo;s DNS name in its &lt;code&gt;memberlist.join_members&lt;/code&gt; configuration:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;memberlist:
  join_members:
    - dns&amp;#43;gossip-ring.tracing.svc.cluster.local.:7946&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;verify-the-listeners&#34;&gt;Verify the listeners&lt;/h2&gt;
&lt;p&gt;The Tempo container image is distroless and doesn&amp;rsquo;t include a shell or networking utilities. You can&amp;rsquo;t &lt;code&gt;exec&lt;/code&gt; into a Tempo Pod directly to inspect listeners.&lt;/p&gt;
&lt;p&gt;To inspect listening sockets, attach an &lt;a href=&#34;https://kubernetes.io/docs/tasks/debug/debug-application/debug-running-pod/#ephemeral-container&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;ephemeral debug container&lt;/a&gt; that shares the target Pod&amp;rsquo;s network namespace, using a debug image that includes the &lt;code&gt;ss&lt;/code&gt; utility:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;sh&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-sh&#34;&gt;kubectl debug -n tracing -it &amp;lt;pod-name&amp;gt; \
  --image=&amp;lt;your-debug-image&amp;gt; \
  --target=backend-worker \
  -- ss -ltn&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;You should see IPv6 wildcard listeners on the memberlist, gRPC, and HTTP ports:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;text&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-text&#34;&gt;State   Recv-Q   Send-Q     Local Address:Port     Peer Address:Port
LISTEN  0        4096                   *:7946                *:*
LISTEN  0        4096                   *:9095                *:*
LISTEN  0        4096                   *:3200                *:*&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The &lt;code&gt;*&lt;/code&gt; in &lt;code&gt;Local Address&lt;/code&gt; indicates the process is listening on all addresses for the configured family.&lt;/p&gt;
]]></content><description>&lt;h1 id="configure-ipv6">Configure IPv6&lt;/h1>
&lt;p>Tempo can be configured to communicate between the components using Internet Protocol Version 6, or IPv6.&lt;/p>
&lt;div class="admonition admonition-note">&lt;blockquote>&lt;p class="title text-uppercase">Note&lt;/p>&lt;p>The underlying infrastructure must support this address family. This configuration may be used in a single-stack IPv6 environment, or in a dual-stack environment where both IPv6 and IPv4 are present. In a dual-stack scenario, only one address family may be configured at a time, and all components must be configured for that address family.&lt;/p></description></item><item><title>Configure TLS communication</title><link>https://grafana.com/docs/tempo/v3.0.x/configuration/network/tls/</link><pubDate>Thu, 28 May 2026 17:50:33 +0100</pubDate><guid>https://grafana.com/docs/tempo/v3.0.x/configuration/network/tls/</guid><content><![CDATA[&lt;h1 id=&#34;configure-tls-communication&#34;&gt;Configure TLS communication&lt;/h1&gt;
&lt;p&gt;Tempo can be configured to communicate between components using Transport Layer Security, or TLS.
TLS secures three categories of connections:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Server and client: Communication between internal Tempo components (for example, querier to query-frontend).&lt;/li&gt;
&lt;li&gt;Receiver: Incoming trace data from instrumented applications or collectors to the distributor.&lt;/li&gt;
&lt;li&gt;Storage and cache: Connections to backend object storage (S3) and caches (Memcached, Redis).&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The ciphers and TLS version here are for example purposes only. We aren&amp;rsquo;t recommending which ciphers or TLS versions to use in production environments.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h2 id=&#34;server-configuration&#34;&gt;Server configuration&lt;/h2&gt;
&lt;p&gt;Every Tempo component exposes gRPC and HTTP endpoints. Use the &lt;code&gt;server&lt;/code&gt; block to enable TLS on these endpoints.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;server:
  tls_cipher_suites: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  tls_min_version: VersionTLS12

  grpc_tls_config:
    cert_file: /tls/tls.crt
    key_file: /tls/tls.key
    client_auth_type: VerifyClientCertIfGiven
    client_ca_file: /tls/ca.crt
  http_tls_config:
    cert_file: /tls/tls.crt
    key_file: /tls/tls.key
    client_auth_type: VerifyClientCertIfGiven
    client_ca_file: /tls/ca.crt&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Valid values for the &lt;code&gt;client_auth_type&lt;/code&gt; are documented in the standard &lt;code&gt;crypto/tls&lt;/code&gt; package under &lt;a href=&#34;https://pkg.go.dev/crypto/tls#ClientAuthType&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;ClientAuthType&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;client-configuration&#34;&gt;Client configuration&lt;/h2&gt;
&lt;p&gt;Several Tempo components configure gRPC clients to communicate with other components. For example, the querier contacts the query-frontend to request work. If the server endpoint uses TLS, the corresponding client must also enable TLS.&lt;/p&gt;
&lt;p&gt;Tempo uses a standard &lt;code&gt;grpc_client_config&lt;/code&gt; stanza for each of these client connections.&lt;/p&gt;
&lt;p&gt;You can optionally omit &lt;code&gt;tls_min_version&lt;/code&gt;, &lt;code&gt;tls_cipher_suites&lt;/code&gt;, and &lt;code&gt;tls_insecure_skip_verify&lt;/code&gt;. Whether &lt;code&gt;tls_server_name&lt;/code&gt; is required depends on your environment.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;grpc_client_config:
  tls_enabled: true
  tls_cert_path: /tls/tls.crt
  tls_key_path: /tls/tls.key
  tls_ca_path: /tls/ca.crt
  tls_server_name: tempo.trace.svc.cluster.local
  tls_insecure_skip_verify: false
  tls_cipher_suites: TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  tls_min_version: VersionTLS12&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Set this configuration block at the following locations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;live_store_client.grpc_client_config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;querier.frontend_worker.grpc_client_config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;backend_scheduler_client.grpc_client_config&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Additionally, &lt;code&gt;memberlist&lt;/code&gt; must also be configured, but the client configuration is nested directly under &lt;code&gt;memberlist&lt;/code&gt; as follows. The same configuration options are available as above.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;memberlist:
    tls_enabled: true
    tls_cert_path: /tls/tls.crt
    tls_key_path: /tls/tls.key
    tls_ca_path: /tls/ca.crt
    tls_server_name: tempo.trace.svc.cluster.local
    tls_insecure_skip_verify: false&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;receiver-tls&#34;&gt;Receiver TLS&lt;/h2&gt;
&lt;p&gt;Receiver TLS secures the connection between trace sources, such as instrumented applications, OpenTelemetry Collectors, or Grafana Alloy, and the Tempo distributor.
The receiver configuration uses the OpenTelemetry Collector TLS settings.
For the full set of options, refer to the upstream &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector/blob/main/receiver/otlpreceiver/config.md#configtls-tlsserversetting&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;OTLP receiver TLS documentation&lt;/a&gt; and the &lt;a href=&#34;https://github.com/open-telemetry/opentelemetry-collector/tree/main/config/configtls&#34; target=&#34;_blank&#34; rel=&#34;noopener noreferrer&#34;&gt;&lt;code&gt;configtls&lt;/code&gt; package reference&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;tls-fields&#34;&gt;TLS fields&lt;/h3&gt;
&lt;p&gt;The following fields are available in the receiver &lt;code&gt;tls&lt;/code&gt; block:&lt;/p&gt;
&lt;section class=&#34;expand-table-wrapper&#34;&gt;&lt;div class=&#34;button-div&#34;&gt;
      &lt;button class=&#34;expand-table-btn&#34;&gt;Expand table&lt;/button&gt;
    &lt;/div&gt;&lt;div class=&#34;responsive-table-wrapper&#34;&gt;
    &lt;table&gt;
      &lt;thead&gt;
          &lt;tr&gt;
              &lt;th&gt;Field&lt;/th&gt;
              &lt;th&gt;Required&lt;/th&gt;
              &lt;th&gt;Description&lt;/th&gt;
          &lt;/tr&gt;
      &lt;/thead&gt;
      &lt;tbody&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;cert_file&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Yes&lt;/td&gt;
              &lt;td&gt;Path to the TLS certificate file.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;key_file&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;Yes&lt;/td&gt;
              &lt;td&gt;Path to the TLS private key file.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;ca_file&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;No&lt;/td&gt;
              &lt;td&gt;Path to a CA certificate bundle used by a TLS &lt;strong&gt;client&lt;/strong&gt; to verify the server&amp;rsquo;s certificate. Use this field on the sending side (for example, in an Alloy exporter or Kafka client) to trust a custom or internal CA. On receivers, this field has no effect because receivers don&amp;rsquo;t initiate outbound TLS connections. If omitted, the system root CA pool is used.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;client_ca_file&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;No&lt;/td&gt;
              &lt;td&gt;Path to the CA certificate used by a TLS &lt;strong&gt;server&lt;/strong&gt; to verify client certificates. When set on a receiver, it requires connecting clients to present a valid certificate signed by this CA (mTLS). Use this field to enable mTLS on receivers.&lt;/td&gt;
          &lt;/tr&gt;
          &lt;tr&gt;
              &lt;td&gt;&lt;code&gt;min_version&lt;/code&gt;&lt;/td&gt;
              &lt;td&gt;No&lt;/td&gt;
              &lt;td&gt;Minimum TLS version to accept, for example &lt;code&gt;&amp;quot;1.2&amp;quot;&lt;/code&gt; or &lt;code&gt;&amp;quot;1.3&amp;quot;&lt;/code&gt;.&lt;/td&gt;
          &lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;
  &lt;/div&gt;
&lt;/section&gt;&lt;h3 id=&#34;configure-server-only-tls&#34;&gt;Configure server-only TLS&lt;/h3&gt;
&lt;p&gt;For server-only TLS, the distributor presents its certificate and clients verify it.
Only &lt;code&gt;cert_file&lt;/code&gt; and &lt;code&gt;key_file&lt;/code&gt; are required:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          tls:
            cert_file: /tls/tls.crt
            key_file: /tls/tls.key
            min_version: &amp;#34;1.2&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;configure-mutual-tls-mtls&#34;&gt;Configure mutual TLS (mTLS)&lt;/h3&gt;
&lt;p&gt;For mutual TLS, both the server and client present certificates.
Add &lt;code&gt;client_ca_file&lt;/code&gt; so the distributor requires and verifies client certificates:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;distributor:
  receivers:
    otlp:
      protocols:
        grpc:
          tls:
            cert_file: /tls/tls.crt
            key_file: /tls/tls.key
            client_ca_file: /tls/ca.crt
            min_version: &amp;#34;1.2&amp;#34;&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h3 id=&#34;supported-receiver-tls-paths&#34;&gt;Supported receiver TLS paths&lt;/h3&gt;
&lt;p&gt;You can set a &lt;code&gt;tls&lt;/code&gt; block on the following receiver configurations:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.otlp.protocols.grpc.tls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.otlp.protocols.http.tls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.kafka.tls&lt;/code&gt; (client TLS for connecting to Kafka brokers)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.zipkin.tls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.jaeger.protocols.grpc.tls&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;distributor.receivers.jaeger.protocols.thrift_http.tls&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&#34;admonition admonition-note&#34;&gt;&lt;blockquote&gt;&lt;p class=&#34;title text-uppercase&#34;&gt;Note&lt;/p&gt;&lt;p&gt;The Kafka receiver TLS block configures &lt;strong&gt;client&lt;/strong&gt; TLS for the connection to Kafka brokers, unlike the other receiver TLS blocks which configure &lt;strong&gt;server&lt;/strong&gt; TLS for incoming connections.&lt;/p&gt;&lt;/blockquote&gt;&lt;/div&gt;

&lt;h3 id=&#34;configure-the-sending-side&#34;&gt;Configure the sending side&lt;/h3&gt;
&lt;p&gt;When you enable TLS on the Tempo receiver, you must also configure TLS on the client that sends traces.
The following example shows a matching Grafana Alloy configuration for an OTLP gRPC exporter with server-only TLS:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;tempo&amp;#34; {
  client {
    endpoint = &amp;#34;tempo.trace.svc.cluster.local:4317&amp;#34;
    tls {
      ca_file = &amp;#34;/tls/ca.crt&amp;#34;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;For mTLS, include the client certificate and key:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;Alloy&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-alloy&#34;&gt;otelcol.exporter.otlp &amp;#34;tempo&amp;#34; {
  client {
    endpoint = &amp;#34;tempo.trace.svc.cluster.local:4317&amp;#34;
    tls {
      ca_file   = &amp;#34;/tls/ca.crt&amp;#34;
      cert_file = &amp;#34;/tls/tls.crt&amp;#34;
      key_file  = &amp;#34;/tls/tls.key&amp;#34;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;storage-and-cache-tls&#34;&gt;Storage and cache TLS&lt;/h2&gt;
&lt;h3 id=&#34;s3-and-s3-compatible-storage&#34;&gt;S3 and S3-compatible storage&lt;/h3&gt;
&lt;p&gt;If you use a self-managed S3-compatible backend (for example, MinIO) with a custom CA or client certificates, configure TLS on the S3 storage backend.
The TLS fields are set inline under &lt;code&gt;storage.trace.s3&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;storage:
  trace:
    backend: s3
    s3:
      bucket: tempo-traces
      endpoint: minio.example.com:9000
      tls_ca_path: /tls/ca.crt
      tls_cert_path: /tls/tls.crt
      tls_key_path: /tls/tls.key
      tls_server_name: minio.example.com
      tls_insecure_skip_verify: false
      tls_min_version: VersionTLS12&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;GCS and Azure Blob Storage rely on their respective SDK defaults for TLS and don&amp;rsquo;t expose separate TLS fields in the Tempo configuration.&lt;/p&gt;
&lt;h3 id=&#34;redis-cache&#34;&gt;Redis cache&lt;/h3&gt;
&lt;p&gt;If you use Redis as a cache backend, enable TLS with the &lt;code&gt;tls_enabled&lt;/code&gt; field.
Redis TLS has limited configuration. It supports &lt;code&gt;tls_enabled&lt;/code&gt; and &lt;code&gt;tls_insecure_skip_verify&lt;/code&gt; but doesn&amp;rsquo;t expose CA or client certificate path fields:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;cache:
  caches:
    - redis:
        endpoint: redis.example.com:6380
        tls_enabled: true
        tls_insecure_skip_verify: false
      roles:
        - parquet-footer
        - bloom
        - frontend-search&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;h2 id=&#34;gateway-and-ingress-tls&#34;&gt;Gateway and ingress TLS&lt;/h2&gt;
&lt;p&gt;Tempo doesn&amp;rsquo;t include a built-in gateway component.
If you end TLS at an ingress controller, load balancer, or reverse proxy in front of Tempo, configure TLS on that component rather than in the Tempo configuration.
When TLS is ended at the ingress, Tempo receivers don&amp;rsquo;t need TLS configured for internal connections.&lt;/p&gt;
&lt;h2 id=&#34;configure-tls-with-helm&#34;&gt;Configure TLS with Helm&lt;/h2&gt;
&lt;p&gt;To configure TLS with the Helm chart, you must have a TLS key-pair and CA certificate stored in a Kubernetes secret.
The following example mounts a secret called &lt;code&gt;tempo-distributed-tls&lt;/code&gt; into the pods at &lt;code&gt;/tls&lt;/code&gt; and modifies the configuration of Tempo to use the files.
In this example, the Tempo components share a single TLS certificate.
The &lt;code&gt;tls_server_name&lt;/code&gt; configuration must match the certificate.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;distributor:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
blockBuilder:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
liveStore:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
backendScheduler:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
backendWorker:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
memcached:
  extraArgs:
    - -Z
    - -o
    - ssl_chain_cert=/tls/tls.crt,ssl_key=/tls/tls.key
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
metricsGenerator:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
querier:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
queryFrontend:
  extraVolumeMounts:
    - mountPath: /tls
      name: tempo-distributed-tls
  extraVolumes:
    - name: tempo-distributed-tls
      secret:
        secretName: tempo-distributed-tls
tempo:
  readinessProbe:
    httpGet:
      scheme: HTTPS
  structuredConfig:
    memberlist:
      tls_ca_path: /tls/ca.crt
      tls_cert_path: /tls/tls.crt
      tls_enabled: true
      tls_key_path: /tls/tls.key
      tls_server_name: tempo-distributed.trace.svc.cluster.local
    distributor:
      receivers:
        otlp:
          protocols:
            grpc:
              tls:
                ca_file: /tls/ca.crt
                cert_file: /tls/tls.crt
                key_file: /tls/tls.key
    live_store_client:
      grpc_client_config:
        tls_ca_path: /tls/ca.crt
        tls_cert_path: /tls/tls.crt
        tls_enabled: true
        tls_key_path: /tls/tls.key
        tls_server_name: tempo-distributed.trace.svc.cluster.local
    backend_scheduler_client:
      grpc_client_config:
        tls_ca_path: /tls/ca.crt
        tls_cert_path: /tls/tls.crt
        tls_enabled: true
        tls_key_path: /tls/tls.key
        tls_server_name: tempo-distributed.trace.svc.cluster.local
    cache:
      caches:
        - memcached:
            consistent_hash: true
            host: tempo-distributed-memcached
            service: memcached-client
            timeout: 500ms
            tls_ca_path: /tls/ca.crt
            tls_cert_path: /tls/tls.crt
            tls_enabled: true
            tls_key_path: /tls/tls.key
            tls_server_name: tempo-distributed.trace.svc.cluster.local
          roles:
            - parquet-footer
            - bloom
            - frontend-search
    querier:
      frontend_worker:
        grpc_client_config:
          tls_ca_path: /tls/ca.crt
          tls_cert_path: /tls/tls.crt
          tls_enabled: true
          tls_key_path: /tls/tls.key
          tls_server_name: tempo-distributed.trace.svc.cluster.local
    server:
      grpc_tls_config:
        cert_file: /tls/tls.crt
        client_auth_type: VerifyClientCertIfGiven
        client_ca_file: /tls/ca.crt
        key_file: /tls/tls.key
      http_tls_config:
        cert_file: /tls/tls.crt
        client_auth_type: VerifyClientCertIfGiven
        client_ca_file: /tls/ca.crt
        key_file: /tls/tls.key
traces:
  otlp:
    grpc:
      enabled: true&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Refer to the 
    &lt;a href=&#34;/docs/alloy/v3.0.x/reference/components/prometheus/prometheus.scrape/&#34;&gt;&lt;code&gt;prometheus.scrape&lt;/code&gt; docs for Alloy&lt;/a&gt; to configure TLS on the scrape.
A relabel configuration like the following does this configuration for you dynamically.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;JSON&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-json&#34;&gt;{
  source_labels: [&amp;#39;__meta_kubernetes_pod_annotation_prometheus_io_scheme&amp;#39;],
  action: &amp;#39;replace&amp;#39;,
  target_label: &amp;#39;__scheme__&amp;#39;,
  regex: &amp;#39;(https?)&amp;#39;,
  replacement: &amp;#39;$1&amp;#39;,
},&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
]]></content><description>&lt;h1 id="configure-tls-communication">Configure TLS communication&lt;/h1>
&lt;p>Tempo can be configured to communicate between components using Transport Layer Security, or TLS.
TLS secures three categories of connections:&lt;/p>
&lt;ul>
&lt;li>Server and client: Communication between internal Tempo components (for example, querier to query-frontend).&lt;/li>
&lt;li>Receiver: Incoming trace data from instrumented applications or collectors to the distributor.&lt;/li>
&lt;li>Storage and cache: Connections to backend object storage (S3) and caches (Memcached, Redis).&lt;/li>
&lt;/ul>
&lt;div class="admonition admonition-note">&lt;blockquote>&lt;p class="title text-uppercase">Note&lt;/p></description></item><item><title>Run Tempo distributed with sidecar proxies</title><link>https://grafana.com/docs/tempo/v3.0.x/configuration/network/sidecar-proxy/</link><pubDate>Thu, 28 May 2026 17:50:33 +0100</pubDate><guid>https://grafana.com/docs/tempo/v3.0.x/configuration/network/sidecar-proxy/</guid><content><![CDATA[&lt;h1 id=&#34;run-tempo-distributed-with-sidecar-proxies&#34;&gt;Run Tempo distributed with sidecar proxies&lt;/h1&gt;
&lt;p&gt;You can route inter-pod gRPC traffic through a sidecar proxy to meet requirements such as custom security, routing, or logging.
Common examples include Envoy, Nginx, Traefik, or service meshes like Istio and Linkerd.&lt;/p&gt;
&lt;p&gt;This page applies only to the 
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/deployment-modes/&#34;&gt;microservices deployment mode&lt;/a&gt;.
In monolithic (single-binary) mode, components communicate in-process, so there&amp;rsquo;s no inter-pod gRPC traffic for a sidecar to proxy.&lt;/p&gt;
&lt;h2 id=&#34;how-tempo-pods-communicate&#34;&gt;How Tempo pods communicate&lt;/h2&gt;
&lt;p&gt;In microservices mode, Tempo&amp;rsquo;s write path runs through Kafka and the read path uses gRPC.
Distributors write to Kafka, and live-stores, block-builders, and metrics-generators each consume from Kafka independently.
Queriers contact live-stores over gRPC for recent data.&lt;/p&gt;
&lt;p&gt;For background on how each component communicates, refer to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/deployment-modes/&#34;&gt;Deployment modes&lt;/a&gt; for the overall network model.&lt;/li&gt;
&lt;li&gt;
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/components/live-store/&#34;&gt;Live-store&lt;/a&gt; and 
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/components/querier/&#34;&gt;Querier&lt;/a&gt; for the gRPC read path that this page covers.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This page focuses on the querier-to-live-store gRPC traffic, which a sidecar proxy can wrap.
Queriers discover live-stores through a shared hash ring: live-stores register their address and port in the ring at startup and deregister on exit.&lt;/p&gt;
&lt;p&gt;The overall network looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/static/img/docs/tempo/sidecar-proxy/tempo-network-sidecar-proxy-simple.svg&#34;
  alt=&#34;Tempo distributed network overview&#34;/&gt;&lt;/p&gt;
&lt;p&gt;You can view the low-level ring data by browsing to the &lt;code&gt;/live-store/ring&lt;/code&gt; URL on any component that imports the live-store ring, for example a distributor or querier. It looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/static/img/docs/tempo/sidecar-proxy/screenshot-tempo-sidecar.png&#34;
  alt=&#34;Ring status with default port&#34; width=&#34;722&#34;
     height=&#34;298&#34;/&gt;&lt;/p&gt;
&lt;p&gt;By default, gRPC traffic uses port 9095, but you can change it by customizing &lt;code&gt;server.grpc_listen_port&lt;/code&gt; on each pod that needs it.
This setting changes the gRPC port for the entire process, so make sure any other components that connect to the pod, for example queriers connecting to a query-frontend, use the new port too.&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;server:
  grpc_listen_port: 12345&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The ring contents reflect the new port:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/static/img/docs/tempo/sidecar-proxy/screenshot-tempo-sidecar-proxies.png&#34;
  alt=&#34;Ring status with updated ports&#34; width=&#34;723&#34;
     height=&#34;310&#34;/&gt;&lt;/p&gt;
&lt;h2 id=&#34;run-tempo-with-proxies&#34;&gt;Run Tempo with proxies&lt;/h2&gt;
&lt;p&gt;Some installations require that the inter-pod gRPC traffic runs through a sidecar proxy.
Running Tempo with proxies requires setting two ports for the live-store: one for the live-store process and one for the sidecar.
Additionally, the live-store ring contents must reflect the proxy&amp;rsquo;s port so that traffic from queriers goes through the proxy.&lt;/p&gt;
&lt;p&gt;The overall network looks like this:&lt;/p&gt;
&lt;p&gt;&lt;img
  class=&#34;lazyload d-inline-block&#34;
  data-src=&#34;/static/img/docs/tempo/sidecar-proxy/tempo-network-sidecar-proxy-complex.svg&#34;
  alt=&#34;Tempo distributed network with sidecar proxies&#34;/&gt;&lt;/p&gt;
&lt;p&gt;You can&amp;rsquo;t accomplish this by setting the same &lt;code&gt;grpc_listen_port&lt;/code&gt; as in the previous example. Instead, the live-store needs to &lt;em&gt;listen&lt;/em&gt; on port A but &lt;em&gt;advertise&lt;/em&gt; itself on port B. To do this, customize the live-store&amp;rsquo;s ring instance port:&lt;/p&gt;

&lt;div class=&#34;code-snippet &#34;&gt;&lt;div class=&#34;lang-toolbar&#34;&gt;
    &lt;span class=&#34;lang-toolbar__item lang-toolbar__item-active&#34;&gt;YAML&lt;/span&gt;
    &lt;span class=&#34;code-clipboard&#34;&gt;
      &lt;button x-data=&#34;app_code_snippet()&#34; x-init=&#34;init()&#34; @click=&#34;copy()&#34;&gt;
        &lt;img class=&#34;code-clipboard__icon&#34; src=&#34;/media/images/icons/icon-copy-small-2.svg&#34; alt=&#34;Copy code to clipboard&#34; width=&#34;14&#34; height=&#34;13&#34;&gt;
        &lt;span&gt;Copy&lt;/span&gt;
      &lt;/button&gt;
    &lt;/span&gt;
    &lt;div class=&#34;lang-toolbar__border&#34;&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;div class=&#34;code-snippet &#34;&gt;
    &lt;pre data-expanded=&#34;false&#34;&gt;&lt;code class=&#34;language-yaml&#34;&gt;live_store:
  ring:
    instance_port: 12345&lt;/code&gt;&lt;/pre&gt;
  &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;The live-store now listens for regular traffic on port 9095, but queriers route traffic to it on port 12345.&lt;/p&gt;
&lt;h2 id=&#34;other-components&#34;&gt;Other components&lt;/h2&gt;
&lt;p&gt;Only the live-store ring&amp;rsquo;s &lt;code&gt;instance_port&lt;/code&gt; is relevant for this sidecar proxy pattern.
Other components have their own rings, but those rings aren&amp;rsquo;t used by queriers for gRPC routing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The metrics-generator consumes trace data from Kafka in microservices mode, so distributors don&amp;rsquo;t reach it through a hash ring. Refer to the 
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/components/metrics-generator/&#34;&gt;metrics-generator architecture&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Distributors and block-builders also use Kafka for the write path. Refer to the 
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/components/distributor/&#34;&gt;distributor&lt;/a&gt; and 
    &lt;a href=&#34;/docs/tempo/v3.0.x/reference-tempo-architecture/partition-ring/&#34;&gt;partition ring&lt;/a&gt; documentation.&lt;/li&gt;
&lt;li&gt;For other gRPC connections, such as querier-to-query-frontend, set &lt;code&gt;server.grpc_listen_port&lt;/code&gt; on the destination pod and update the matching client address on the calling component.&lt;/li&gt;
&lt;/ul&gt;
]]></content><description>&lt;h1 id="run-tempo-distributed-with-sidecar-proxies">Run Tempo distributed with sidecar proxies&lt;/h1>
&lt;p>You can route inter-pod gRPC traffic through a sidecar proxy to meet requirements such as custom security, routing, or logging.
Common examples include Envoy, Nginx, Traefik, or service meshes like Istio and Linkerd.&lt;/p></description></item></channel></rss>