Repository navigation
feat: add TransportOptions for configuring TLS, proxy, and default headers - #122
Conversation
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.
There was a problem hiding this comment.
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.
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.
There was a problem hiding this comment.
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.
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.
There was a problem hiding this comment.
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.
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.
…inks to transport-aware overloads in Zitadel entry\npoint and remove stray inline comment from OpenId constructor.
…xt as Python, Ruby, and PHP.
…otbugs.xml exclusions with inline @SuppressFBWarnings\nannotations on ApiClient and OpenId. The OAuthAuthenticatorBuilder\nsuppression is no longer needed.
Preserve the original (OpenId, Scope) constructor signature by delegating to the new 3-param overload with null transport options.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 6 comments.
Comments suppressed due to low confidence (1)
src/main/java/com/zitadel/auth/OAuthAuthenticator.java:112
- Same as
OpenId: the proxy URL scheme is ignored and aProxy.Type.HTTPis always configured. This makeshttps://proxy URLs misleading (and behavior differs fromApiClient, which uses the proxy scheme). Consider restricting tohttp://with a clear exception or implementing consistent HTTPS-proxy handling.
protected abstract AuthorizationGrant getGrant();
protected Token getToken(ClientAuthentication authentication) throws ZitadelException {
try {
URI tokenEndpoint = openId.getTokenEndpoint().toURI();
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Align transport options test with the version used in other tests.
Align description with the other SDKs.
Replace with the actual class name WebTokenAuthenticator.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 12 out of 13 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
WireMock auto-loads JSON files from /home/wiremock/mappings/ at startup, so there is no need to register stubs via the admin API in test setup.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 17 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.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 16 out of 17 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
# [4.1.0-beta.11](v4.1.0-beta.10...v4.1.0-beta.11) (2026-03-10) ### Features * add TransportOptions for configuring TLS, proxy, and default headers ([#122](#122)) ([d4f8b48](d4f8b48))
# [4.1.0](v4.0.0...v4.1.0) (2026-03-17) ### Bug Fixes * add getter methods for API services to improve testability ([#82](#82)) ([385234a](385234a)) * **build:** enable the pipeline to also run the commitlint checks ([ff7a86d](ff7a86d)) * **build:** fix the name of the docker-related dependabot updates [skip ci] ([303fb78](303fb78)) * **build:** trigger pipeline only on all branches for push [skip ci] ([d046b01](d046b01)) ### Features * add TransportOptions for configuring TLS, proxy, and default headers ([#122](#122)) ([d4f8b48](d4f8b48)) * added InputStream support for private key authentication ([#99](#99)) ([ac8c534](ac8c534)) * **build:** added a workflow to find unused dependencies ([#85](#85)) ([571b04a](571b04a)) * initial beta sdk release for Zitadel v4.0.0-rc.1 ([eec6909](eec6909)) * **sdk:** generate SDK for version v4.0.0 ([#89](#89)) ([38275ee](38275ee)) * **sdk:** generate SDK for version v4.1.3 ([#101](#101)) ([c0425ff](c0425ff)) * **sdk:** generate SDK for version v4.11.0 ([#120](#120)) ([323e737](323e737)) * **sdk:** generate SDK for version v4.2.0 ([#102](#102)) ([b063b41](b063b41)) * **sdk:** generate SDK for version v4.3.0 ([#105](#105)) ([37c5ec6](37c5ec6))
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 newTransportOptionsclass 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 withTransportOptionsare 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
TransportOptionsTest) verifies custom CA certs, insecure mode, default headers, proxy URLs, and the failure case when connecting to HTTPS without a trusted cert — all usingTransportOptionsobjects passed towithClientCredentials.Documentation
The README has been updated with transport options examples under Advanced Configuration showing
TransportOptionsusage for each setting.Checklist