Skip to content

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

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

feat: add TransportOptions for configuring TLS, proxy, and default headers#122
mridang wants to merge 20 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 (withAccessToken, withClientCredentials, withPrivateKey). The existing method signatures are unchanged — the new overloads with TransportOptions are purely additive, 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 original method signatures.
  • A new integration test (TransportOptionsTest) verifies custom CA certs, insecure mode, default headers, proxy URLs, and the failure case when connecting to HTTPS without a trusted cert — all using TransportOptions objects passed to withClientCredentials.
  • The full test suite runs against a WireMock Docker container with HTTPS support via Testcontainers.
  • Format, lint, static analysis, and dependency checks all pass.

Documentation

The README has been updated with transport options examples under Advanced Configuration showing TransportOptions.Builder usage for each setting.

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 (defaultHeaders, caCertPath, insecure, proxyUrl). Factory
methods now have overloads accepting TransportOptions alongside the
existing signatures for backward compatibility. Internal auth plumbing
(OpenId, builders) refactored to use TransportOptions throughout.
@mridang mridang self-assigned this Mar 4, 2026
@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 requested a review from Copilot March 4, 2026 02:52
Copy link
Contributor

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 (custom CA certs, insecure TLS, proxy routing, and default headers) and threads it through Zitadel client factory methods, authenticators, OpenID discovery, and the API HTTP client.

Changes:

  • Introduce TransportOptions (+ builder) and new Zitadel factory overloads accepting it.
  • Apply transport options to OpenID discovery (OpenId) and to API calls via Apache HttpClient (ApiClient).
  • Add README “Advanced Configuration” examples and a new integration-style test suite for transport options.

Reviewed changes

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

Show a summary per file
File Description
src/main/java/com/zitadel/TransportOptions.java New immutable options object + builder for headers, proxy, TLS flags, and CA cert path.
src/main/java/com/zitadel/Zitadel.java Add factory overloads/constructors that accept TransportOptions and build ApiClient with it.
src/main/java/com/zitadel/ApiClient.java Build Apache HttpClient with proxy, default headers, and TLS customization based on TransportOptions.
src/main/java/com/zitadel/auth/OpenId.java Apply proxy/TLS/default headers during OpenID discovery request.
src/main/java/com/zitadel/auth/OAuthAuthenticator.java Thread TransportOptions into builder construction (via OpenId), plus add a setter.
src/main/java/com/zitadel/auth/ClientCredentialsAuthenticator.java Add builder overload accepting TransportOptions.
src/main/java/com/zitadel/auth/WebTokenAuthenticator.java Add overloads accepting TransportOptions for JSON-based construction and builder creation.
src/test/java/com/zitadel/TransportOptionsTest.java New Testcontainers/WireMock-based test coverage for transport options scenarios.
README.md Document transport options usage patterns and examples.
spotbugs.xml Add suppressions related to intentional insecure TLS and broad exception handling in transport setup.

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

mridang added 4 commits March 4, 2026 14:09
When a custom CA certificate is configured, the previous implementation
created an empty KeyStore and only added the custom cert, which dropped
all JVM default trust anchors. This meant connections to hosts using
publicly-trusted certificates would fail. Now the default trusted certs
are loaded into the KeyStore alongside the custom CA.
Copy link
Contributor

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 10 out of 10 changed files in this pull request and generated 8 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.
Fix testProxyUrl to actually call withClientCredentials, add
testTransportOptionsObject test, and add proxy credential support.
Default to TransportOptions.defaults() when null is passed,
consistent with all other SDK entry points.
OpenId, OAuthAuthenticator, and OAuthAuthenticatorBuilder now
default to TransportOptions.defaults() when null is passed,
consistent with all other SDKs.
Fail fast with IllegalArgumentException when null or blank header
name or null value is passed to defaultHeader().
Extract duplicated SSL context construction from OAuthAuthenticator,
OpenId, and ApiClient into TransportOptions.buildSSLContext().
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.
Remove unnecessary @SuppressFBWarnings annotation from getToken.
Change proxy test to use withAccessToken instead of withClientCredentials
since WireMock cannot act as an HTTP proxy for OpenID discovery.
Build the SSLContext once on first use and cache it using
double-checked locking. This avoids repeated disk reads of
the CA cert file and redundant keystore construction on every
token request.
The installation section incorrectly showed the PHP composer
command instead of the Maven dependency XML block.
The PATH_TRAVERSAL_IN suppression is no longer needed on the public
caching wrapper since the file I/O moved to buildSSLContextInternal.
Copy link
Contributor

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 11 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 3 commits March 5, 2026 00:29
Add <removeUnusedImports/> to the Spotless Maven plugin config so
unused imports are automatically stripped during formatting.
Leftover imports from when SSL/TLS code was moved to TransportOptions.
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