Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion temporalio/bridge/sdk-core
Submodule sdk-core updated 106 files
12 changes: 6 additions & 6 deletions temporalio/envconfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
class ClientConfigTLSDict(TypedDict, total=False):
"""Dictionary representation of TLS config for TOML."""

disabled: bool
disabled: Optional[bool]
server_name: str
server_ca_cert: Mapping[str, str]
client_cert: Mapping[str, str]
Expand Down Expand Up @@ -105,8 +105,8 @@ class ClientConfigTLS:
Experimental API.
"""

disabled: bool = False
"""If true, TLS is explicitly disabled."""
disabled: Optional[bool] = None
"""If True, TLS is explicitly disabled. If False, TLS is explicitly enabled. If None, TLS behavior was not configured."""
server_name: Optional[str] = None
"""SNI override."""
server_root_ca_cert: Optional[DataSource] = None
Expand All @@ -119,7 +119,7 @@ class ClientConfigTLS:
def to_dict(self) -> ClientConfigTLSDict:
"""Convert to a dictionary that can be used for TOML serialization."""
d: ClientConfigTLSDict = {}
if self.disabled:
if self.disabled is not None:
d["disabled"] = self.disabled
if self.server_name is not None:
d["server_name"] = self.server_name
Expand All @@ -138,7 +138,7 @@ def set_source(

def to_connect_tls_config(self) -> Union[bool, temporalio.service.TLSConfig]:
Copy link
Member

@cretz cretz Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, the default of TLS (i.e. neither true nor false) was that it was implicitly enabled if there was an API key present, otherwise implicitly disabled. I think we need to respect that behavior in the SDKs (IIRC, Go does).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that is the behaviour of this function, we only return False (instead of a TLSConfig) if disabled is explicitly enabled

Copy link
Contributor Author

@THardy98 THardy98 Sep 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or are you saying that if a user supplies an api key AND sets disabled to explicitly true, that the api-key would take precedence?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For example, this case:

        """
        [profile.default]
        address = "{target_host}"
        [profile.default.tls]
        disabled = false
        server_name = "my-server"
        """

technically, TLS is enabled here, there's no restriction as long as don't set disabled as true. We'd basically pass an empty TLSConfig to the client on the connect call

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the test in this commit lays out the various cases:
9423e82

Copy link
Member

@cretz cretz Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue actually is at to_client_connect_config. So if ClientConfigProfile.api_key is present CleintConfigProfile.tls is None, does tls get enabled? It doesn't seem so from the code, but it should.

Copy link
Contributor Author

@THardy98 THardy98 Sep 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done in core:

  /// Apply automatic TLS enabling when API key is present
  pub fn apply_api_key_tls_logic(&mut self) {
      if self.api_key.is_some() && self.tls.is_none() {
          // If API key is present but no TLS config exists, create one with TLS enabled
          self.tls = Some(ClientConfigTLS::default());
      }
  }

though now, given that we have logic in lang to transform to/from object that should represent the TOML, this may no longer be desired/accurate.

Probably the best solution here is to change pub tls: Option<ClientConfigTLS> in core to:

pub enum ConfigTlsEnum {
    Enabled(bool),          // TLS enabled, default options (i.e. api key but no tls)
    Config(ClientConfigTLS), // TLS explicitly configured
}

and then:

pub tls: Option<ConfigTlsEnum> // null is no api key or TLS configuration

alternatively, we keep core as is and make the change upstream in the bridge, with the logic being something like "if received TLS object is ClientConfigTLS::default(), then transform to true"

or we remove apply_api_key_tls_logic from core altogether and have lang implement this logic

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am leaning towards the latter, will open a PR

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"""Create a `temporalio.service.TLSConfig` from this profile."""
if self.disabled:
if self.disabled is True:
return False

return temporalio.service.TLSConfig(
Expand All @@ -154,7 +154,7 @@ def from_dict(d: Optional[ClientConfigTLSDict]) -> Optional[ClientConfigTLS]:
if not d:
return None
return ClientConfigTLS(
disabled=d.get("disabled", False),
disabled=d.get("disabled"),
server_name=d.get("server_name"),
# Note: Bridge uses snake_case, but TOML uses kebab-case which is
# converted to snake_case. Core has server_ca_cert, client_key.
Expand Down
Loading
Loading