Skip to content

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

Merged
mridang merged 42 commits intobetafrom
feat/add-transport-options
Mar 10, 2026
Merged

feat: add TransportOptions for configuring TLS, proxy, and default headers#79
mridang merged 42 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 (Steep/RBS), 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 class 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 requested a review from Copilot March 4, 2026 02:52
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 TransportOptions abstraction to centralize transport-level configuration (default headers, custom CA, insecure TLS, proxy) and threads it through Zitadel client factory methods and auth/OpenID plumbing while preserving backward compatibility with existing keyword args.

Changes:

  • Introduce Zitadel::Client::TransportOptions (plus RBS typings) and update factory APIs to accept transport_options: alongside individual kwargs.
  • Extend Configuration / ApiClient to support per-client default_headers and proxy_url for API requests.
  • Add integration tests (WireMock + Testcontainers) and update README with “advanced configuration” docs.

Reviewed changes

Copilot reviewed 11 out of 11 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
lib/zitadel/client/transport_options.rb New immutable container for TLS/proxy/header transport settings.
lib/zitadel/client/zitadel.rb Factory methods accept and resolve TransportOptions, apply settings to Configuration.
lib/zitadel/client/configuration.rb Adds default_headers and proxy_url to configuration.
lib/zitadel/client/api_client.rb Merges config.default_headers into request headers; sets Typhoeus proxy option.
lib/zitadel/client/auth/open_id.rb OpenID discovery now honors proxy/CA/insecure/default headers via TransportOptions.
lib/zitadel/client/auth/authenticator.rb OAuth builder now accepts transport_options and passes it to OpenId.
lib/zitadel/client/auth/client_credentials_authenticator.rb Builder accepts transport_options (currently only impacts OpenID discovery).
lib/zitadel/client/auth/web_token_authenticator.rb Builder/from_json accept transport_options (currently only impacts OpenID discovery).
sig/lib.rbs Updates RBS signatures for the new options and new API shapes.
test/zitadel/client/transport_options_test.rb New integration test suite for CA/insecure/headers/proxy init paths.
README.md Documents advanced transport configuration and TransportOptions usage.

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

mridang added 5 commits March 4, 2026 14:11
When a custom CA certificate is configured, the previous implementation
set http.ca_file which replaced the system trust store entirely. Now
an OpenSSL::X509::Store is used with set_default_paths to load system
CAs first, then add_file to include the custom CA alongside them.
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 12 changed files in this pull request and generated 4 comments.


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

mridang added 11 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.
Updates RBS type signatures for transport_options parameters.
Assert 201 on stub registration, fix verify_ssl_host for insecure
mode, add proxy credential support, consistent with all other SDKs.
Frozen hashes from TransportOptions would raise FrozenError if
config or Faraday later tries to mutate the headers hash.
Extract duplicated connection opts construction from authenticators
into TransportOptions#to_connection_opts.
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.
Change HTTP library reference from Faraday to Typhoeus and fix
the debug example to use the configuration block instead of an
unsupported debug: parameter on the factory method.
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
withAccessToken which does not trigger discovery during construction.
Use consistent subsection structure across all SDKs: intro
paragraph, then separate sections for TLS, CA cert, headers,
and proxy with identical explanatory text.
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 14 out of 15 changed files in this pull request and generated 6 comments.


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

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 15 out of 16 changed files in this pull request and generated no new comments.


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

mridang added 3 commits March 9, 2026 09:19
…on with_access_token, with_client_credentials,\nand with_private_key to match the other SDK implementations.
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 15 out of 16 changed files in this pull request and generated 3 comments.


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

mridang and others added 4 commits March 9, 2026 12:41
Align transport options test with the version used in other tests.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Align description with the other SDKs.
Use Testcontainers::DockerContainer and wait_for_tcp_port for the
proxy container instead of raw Docker API and custom port-waiting
logic.
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 15 out of 16 changed files in this pull request and generated 3 comments.


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

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 15 out of 16 changed files in this pull request and generated no new comments.


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

mridang added 5 commits March 9, 2026 16:19
…nWireMock auto-loads JSON files from /home/wiremock/mappings/ at startup,\nso there is no need to register stubs via the admin API in test setup.
…ppings from fixtures/ to test/fixtures/ to match FIXTURES_DIR,\nand chain with_filesystem_binds calls (method accepts a single argument).
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 19 out of 20 changed files in this pull request and generated 1 comment.


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

Comment on lines +145 to +150
config.default_headers = resolved.default_headers.dup
config.ssl_ca_cert = resolved.ca_cert_path if resolved.ca_cert_path
if resolved.insecure
config.verify_ssl = false
config.verify_ssl_host = false
end
Copy link

Copilot AI Mar 9, 2026

Choose a reason for hiding this comment

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

apply_transport_options sets config.ssl_ca_cert whenever ca_cert_path is present, even when insecure is true. This conflicts with TransportOptions#to_connection_opts (where insecure takes precedence) and can cause Typhoeus/libcurl to try to load a CA file even though TLS verification is disabled. Consider skipping/clearing ssl_ca_cert when resolved.insecure is true so insecure reliably overrides ca_cert_path end-to-end.

Copilot uses AI. Check for mistakes.
@mridang mridang merged commit 04caa65 into beta Mar 10, 2026
39 of 41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants