Skip to content

feat: add TransportOptions for configuring TLS, proxy, and default headers#103

Open
mridang wants to merge 14 commits intobetafrom
feat/add-transport-options
Open

feat: add TransportOptions for configuring TLS, proxy, and default headers#103
mridang wants to merge 14 commits intobetafrom
feat/add-transport-options

Conversation

@mridang
Copy link
Collaborator

@mridang mridang commented Mar 4, 2026

Description

This pull request adds support for transport options, allowing users to configure custom CA certificates, disable TLS verification for development environments, route requests through HTTP proxies, and inject default headers (e.g. Proxy-Authorization) into all SDK requests. A new TransportOptions class bundles these four settings into a single reusable object that can be passed to any factory method (with_access_token, with_client_credentials, with_private_key). The existing individual keyword arguments continue to work as before — no breaking changes.

Related Issue

N/A

Motivation and Context

Users deploying Zitadel behind corporate proxies, firewalls, or in environments with self-signed or private CA certificates had no clean way to configure these transport-level settings. This change gives them a single object they can construct once with their proxy URL, CA cert path, TLS preferences, and any extra headers, then pass it to whichever authentication method they use.

How Has This Been Tested

  • All existing tests pass unchanged, confirming backward compatibility with the individual-parameter approach.
  • A new integration test (test_transport_options_object) verifies that a TransportOptions instance can be passed to with_client_credentials and the SDK initializes successfully against a WireMock HTTPS endpoint.
  • The full test suite covers custom CA certs, insecure mode, default headers, proxy URLs, and the failure case when connecting to HTTPS without a trusted cert.
  • Format, lint, type checking, and dependency checks all pass.

Documentation

The README has been updated with a "Using TransportOptions" subsection under Advanced Configuration.

Checklist

  • I have updated the documentation accordingly.
  • I have assigned the correct milestone or created one if non-existent.
  • I have correctly labeled this pull request.
  • I have linked the corresponding issue in this description.
  • I have requested a review from at least 2 reviewers
  • I have checked the base branch of this pull request
  • I have checked my code for any possible security vulnerabilities

Introduce a TransportOptions dataclass that encapsulates transport-level
configuration (default_headers, ca_cert_path, insecure, proxy_url). Factory
methods now accept an optional transport_options parameter alongside the
existing individual parameters for backward compatibility. Internal auth
plumbing (OpenId, builders) refactored to use TransportOptions throughout.
@mridang mridang changed the title Add TransportOptions for configuring TLS, proxy, and default headers feat: add TransportOptions for configuring TLS, proxy, and default headers Mar 4, 2026
@mridang mridang self-assigned this Mar 4, 2026
@mridang mridang added the enhancement New feature or request label Mar 4, 2026
@mridang mridang requested a review from Copilot March 4, 2026 02:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a reusable TransportOptions object to configure transport-layer behavior (TLS, proxies, and headers) across Zitadel SDK factory methods and underlying HTTP plumbing.

Changes:

  • Introduces TransportOptions and wires it into Zitadel.with_* factory methods.
  • Adds support for proxy routing and default headers in the generated API client/REST layer.
  • Extends OpenID discovery to honor transport options (custom CA / insecure / proxy / headers) and adds a new integration test plus README docs.

Reviewed changes

Copilot reviewed 12 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
zitadel_client/zitadel.py Adds TransportOptions support to SDK factory methods via config mutation helpers.
zitadel_client/transport_options.py Introduces the TransportOptions dataclass.
zitadel_client/rest.py Uses urllib3.ProxyManager when Configuration.proxy_url is set.
zitadel_client/configuration.py Adds default_headers and proxy_url to configuration.
zitadel_client/api_client.py Merges Configuration.default_headers into client default headers.
zitadel_client/auth/open_id.py Applies transport options to OpenID discovery request (headers/TLS/proxy).
zitadel_client/auth/oauth_authenticator.py Threads transport options into OpenId construction.
zitadel_client/auth/client_credentials_authenticator.py Accepts/threads transport options through the builder.
zitadel_client/auth/web_token_authenticator.py Accepts/threads transport options through from_json/builder.
zitadel_client/__init__.py Exports TransportOptions at package top-level.
test/test_transport_options.py Adds integration-style coverage for transport options initialization paths.
README.md Documents advanced transport configuration and TransportOptions.
uv.lock Updates package version and dependency layout (notably cryptography).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

mridang added 4 commits March 4, 2026 14:10
frozen=True on the dataclass only prevents field reassignment but the
dict itself could still be mutated in-place. Now default_headers is
wrapped in MappingProxyType on construction, making it a read-only view.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 12 out of 13 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

mridang added 9 commits March 4, 2026 18:57
Use a pre-generated keystore with proper SANs (localhost, 127.0.0.1, ::1)
for WireMock HTTPS instead of extracting certs at runtime. This fixes the
hostname mismatch error on systems where localhost resolves to IPv6.

Also threads transport options through to OAuth token exchange requests so
that custom CA, insecure mode, proxy, and default headers apply end-to-end.
… HttpWaitStrategy instead of manual polling loop\nfor WireMock readiness, consistent with Java, Node, PHP, and Ruby.
MappingProxyType from TransportOptions breaks Configuration's
deepcopy and makes headers unexpectedly immutable.
Extract duplicated session kwargs building from authenticators
into TransportOptions.to_session_kwargs().
Add WireMock stub for settings endpoint and use WireMock's
/__admin/requests/count API to assert custom headers are sent
on actual API calls, not just during initialization.
Factory methods now only accept a TransportOptions object instead of
individual default_headers, ca_cert_path, insecure, and proxy_url
parameters. This matches the Java and Node SDKs.
WireMock cannot act as an HTTP proxy for OpenID discovery, so use
with_access_token which does not trigger discovery during construction.
HttpWaitStrategy is only available in testcontainers 4.x.
Replace with manual HTTP wait using wait_container_is_ready
decorator which is available in the pinned 3.7.1 version.
Use consistent subsection structure across all SDKs: intro
paragraph, then separate sections for TLS, CA cert, headers,
and proxy with identical explanatory text.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants