Skip to content

Runtime TLS configuration with xDS #1817

Description

@zmiklank

Currently, ztunnel TLS settings are configurable via environment variables (TLS12_ENABLED, COMPLIANCE_POLICY=pqc).
This RFC proposes a possibility for ztunnel to receive TLS configuration (protocol versions, cipher suites, key exchange groups) via the Workload API, allowing runtime updates without pod restarts.

I am interested in your opinion on this and I can follow up with a PR with implementation.

Alignment with meshMTLS

Istio's MeshConfig.meshMTLS already provides minProtocolVersion, cipherSuites, and ecdhCurves fields (the ecdhCurves being in progress, tracked in Issue #52290, PR being here).

Proposal

Workload API Extension

Add a TlsProfile message to the Workload API:

enum TlsVersion {
  TLS_1_2 = 0;
  TLS_1_3 = 1;
}

message TlsProfile {
  TlsVersion min_protocol_version = 1;  // Required
  repeated string cipher_suites = 2;     // Empty means use defaults
  repeated string ecdh_curves = 3;       // Empty means use defaults
}

ztunnel Changes

  • Parse TlsProfile from Workload API
  • Apply configuration to HBONE connections (inbound and outbound)
  • Control plane connection (ztunnel ↔ istiod) remains configured via environment variables, matching Envoy's behavior
  • Fall back to environment variables when no profile is set

Istiod Changes

  • Reuse existing MeshConfig.meshMTLS which already has minProtocolVersion, cipherSuites, and ecdhCurves fields
  • Add TlsProfile message to the Workload API protobuf definitions
  • Populate TlsProfile from meshMTLS when generating xDS responses for ztunnel
  • Optionally validate configuration (e.g., warn if TLS 1.2 is enabled without ECDHE_ECDSA cipher suites)

Configuration Priority

  1. Workload API TlsProfile
  2. Environment variables (TLS12_ENABLED, COMPLIANCE_POLICY)
  3. Hardcoded defaults

Backward Compatibility

Fully backward compatible. Missing or empty TlsProfile uses current environment variable behavior.

Known Limitations

  1. BoringSSL (FIPS): Fixed cipher suite set, runtime configuration not possible
  2. Compile-time constraints: Cipher suites must be compiled into the binary to be able to choose them

Open Questions

  1. Unsupported ciphers: Should ztunnel warn and fall back, or reject the configuration?
  2. TLS 1.2 SPIFFE compatibility: Should istiod validate that TLS_ECDHE_ECDSA_* cipher suites are configured when TLS 1.2 is enabled? (Required for SPIFFE mTLS)

Activity

  1. keithmattix commented on Mar 30, 2026

    @keithmattix
    Contributor

    /cc @howardjohn @Stevenjin8 @ilrudie

    IMO, if we're going to solve this, we need to solve runtime mesh settings in ztunnel more generally, including things like trustdomain (/cc @krinkinmu @grnmeira)

  2. howardjohn commented on Mar 30, 2026

    @howardjohn
    Member

    I agree with @keithmattix and also that we should probably be very hesitant to do this. I would imagine that the primary goal here is for compliance which would make dynamic configuration more annoying than useful. Especially FIPS for example where the goal is generally to handle it at compile time.

  3. zmiklank commented on Mar 31, 2026

    @zmiklank
    ContributorAuthor

    IMO, if we're going to solve this, we need to solve runtime mesh settings in ztunnel more generally, including things like trustdomain

    @keithmattix In that case we should also add the possibility to query current config for debugging purposes, similar to what Envoy provides via its config dump.

    we should probably be very hesitant to do this

    @howardjohn Indeed. I think that Ztunnel being so minimalistic is one of its strengths. Thinking hard about adding new features in general is the key to keeping it that way.

    I would imagine that the primary goal here is for compliance which would make dynamic configuration more annoying than useful. Especially FIPS for example where the goal is generally to handle it at compile time.

    I see at least two benefits in adding this xDS configuration:

    First is, as you mentioned, compliance. FIPS is one thing, but all of the cipher suites and kx groups ztunnel offers are FIPS compliant (except the PQC kx group, which is disabled by default). So in general, users who aim to be FIPS compliant can just go with the defaults (+ use FIPS validated crypto lib). However, PQC is becoming more important every year, so I think this could be more important for users who want to use specific crypto (such as the PQC) rather than the defaults.

    Second is transparency. When global mesh options are set via istiod, I see it as more transparent if these settings are also applied to ztunnel, which is part of the mesh too. It is also probably easier for users to configure the whole mesh at once than to set env vars for ztunnel DaemonSets (or using operators to do that for them).

    Per @keithmattix's comment I searched through what could be a good candidates for xDS configuration in ztunnel:

    • Trust Domain
    • Trust Domain Aliases
    • Cluster Domain.

    Do you see any other candidates?

  4. keithmattix commented on Apr 28, 2026

    @keithmattix
    Contributor

    I think this is something we should probably discuss in a design doc or working group meeting. ztunnel has gotten pretty far with just env var/static config; I'm not sure PQC is enough justification for dynamic config. All of the candidate values seem to be things that wouldn't change during the lifetime of a ztunnel

  5. zmiklank commented on Apr 29, 2026

    @zmiklank
    ContributorAuthor

    Sure, that makes sense. I can start writing the design doc then.

  6. howardjohn commented on Apr 29, 2026

    @howardjohn
    Member

    FWIW my initial impression was aligned with Keith's that this seems possibly more complex than the benefits it brings

  7. zmiklank commented on May 11, 2026

    @zmiklank
    ContributorAuthor

    The design doc is published now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions