Skip to content

CNTRLPLANE-3762: Add support for component-scoped proxy#946

Open
tchap wants to merge 9 commits into
openshift:masterfrom
tchap:disconnected-env-review
Open

CNTRLPLANE-3762: Add support for component-scoped proxy#946
tchap wants to merge 9 commits into
openshift:masterfrom
tchap:disconnected-env-review

Conversation

@tchap

@tchap tchap commented Jul 7, 2026

Copy link
Copy Markdown

Add component-scoped proxy support for authentication

Adds support for a per-component proxy configuration on the operator.openshift.io/v1 Authentication CR, gated behind FeatureGateAuthenticationComponentProxy. When enabled, the authentication operator reads spec.proxy (HTTPProxy, HTTPSProxy, NoProxy, TrustedCA) from the Authentication CR instead of relying on the cluster-wide proxy environment variables.

Enhancement: Proxy support for integrated auth stack

Motivation

In disconnected or restricted-network environments, the cluster-wide proxy may not be appropriate for authentication traffic. A component-scoped proxy allows administrators to route OAuth/OIDC and IdP traffic through a dedicated proxy with its own CA trust, independent of the global proxy configuration.

Changes

Cluster-wide proxy: no longer loaded from the proxies.config.openshift.io/cluster API resource. ResolveProxy reads it from the process environment variables (HTTP_PROXY, HTTPS_PROXY, NO_PROXY), which are already injected by the cluster proxy controller. This removes the direct API dependency and the proxyLister/proxyInformer from the deployment controller.

Transport layer (pkg/transport)

  • TransportForCARefWithProxy: builds proxy-aware HTTP transports with configurable CA references.
  • LoadCAData: exported helper that reads CA bundle bytes from a ConfigMap, checking Data first then BinaryData.

Proxy resolution (pkg/controllers/common)

  • ResolveProxy: reads the component proxy from the Authentication CR when the feature gate is enabled; falls back to httpproxy.FromEnvironment() otherwise. Returns a ResolvedProxy with the effective proxy configuration and optional TrustedCAName.

Config observer (pkg/controllers/configobservation/oauth)

  • IDP transport construction uses the resolved proxy settings and appends the proxy trusted CA to CA references.
  • New ObserveProxyTrustedCA observer injects the proxy CA bundle file path into the observed config when a trusted CA is configured.

Deployment controller (pkg/controllers/deployment)

  • Injects HTTP_PROXY/HTTPS_PROXY/NO_PROXY env vars from the resolved proxy into the OAuth Server pod.
  • Syncs the trusted CA ConfigMap from openshift-config to openshift-authentication.
  • Adds a volume/mount with Optional: true for CA hot-reload without redeployment.

Proxy validation controller (pkg/controllers/proxyconfig)

  • Validates route reachability through the resolved proxy (component or cluster-wide).
  • Tests IdP endpoint connectivity and emits IdPEndpointUnreachable warning events for transient failures (does not set Degraded).
  • Uses hash-based change detection to avoid redundant validation.

Endpoint accessible controller (pkg/libs/endpointaccessible)

  • Accepts an optional proxy function for route health checks. Only the route check controller uses it (external hostname); service and endpoint checks remain proxy-free (cluster-internal addresses).

Custom route controller (pkg/controllers/customroute)

  • Route availability health check uses the resolved proxy and loads the proxy trusted CA via LoadCAData.

Test plan

Unit tests are in place, but e2e tests are still missing.

Summary by CodeRabbit

  • New Features
    • OAuth server and route/endpoint accessibility checks now support component-scoped proxy settings (with component-scoped trusted CA support) in addition to cluster-wide proxies.
    • Proxy validation and identity-provider discovery now use CA-aware, proxy-aware transports and deterministic noProxy merging.
  • Bug Fixes
    • When component proxy configuration can’t be read, behavior now safely falls back to cluster-wide proxy settings.
    • Proxying is disabled when no effective proxy is set, and identity-provider reachability warnings are aggregated while avoiding unnecessary revalidation.
  • Tests
    • Added unit coverage for proxy resolution, request proxy selection, and IdP connectivity event behavior.

@openshift-ci-robot

openshift-ci-robot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@tchap: This pull request references CNTRLPLANE-3762 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

This implements the component-scoped proxy enhancement for this operator.

There are no e2e tests as of now.

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 7, 2026
@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 7, 2026
@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@tchap

tchap commented Jul 7, 2026

Copy link
Copy Markdown
Author

/jira refresh

@openshift-ci-robot

openshift-ci-robot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

@tchap: This pull request references CNTRLPLANE-3762 which is a valid jira issue.

Details

In response to this:

/jira refresh

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds component-scoped proxy resolution and threads it through controller wiring, transport creation, deployment generation, route and endpoint checks, and proxy validation. Also updates the module replace directive.

Changes

Component proxy flow

Layer / File(s) Summary
Proxy helpers and module override
go.mod, pkg/controllers/common/proxy.go, pkg/controllers/common/proxy_test.go
Adds component proxy lookup, effective proxy resolution, request-level proxy function construction, and the module replace override, with unit tests covering gate states and proxy selection.
Transport and IdP discovery
pkg/transport/transport.go, pkg/controllers/configobservation/oauth/idp_conversions.go, pkg/controllers/configobservation/oauth/idp_conversions_test.go, pkg/controllers/configobservation/oauth/observe_idps.go
Updates CA transport construction, threads caller-supplied transport builders through IdP conversion, and builds proxy-aware transports while observing IdPs.
Config observation wiring
pkg/controllers/configobservation/interfaces.go, pkg/controllers/configobservation/configobservercontroller/observe_config_controller.go
Extends config observation listers and controller setup to carry operator Authentication access and feature-gate access.
Deployment proxy and CA sync
pkg/controllers/deployment/default_deployment.go, pkg/controllers/deployment/deployment_controller.go
Changes OAuth deployment generation to use resolved proxy strings and adds managed component proxy CA ConfigMap synchronization and volume mounting.
Route and endpoint proxying
pkg/controllers/customroute/custom_route_conditions.go, pkg/controllers/customroute/custom_route_controller.go, pkg/controllers/oauthendpoints/oauth_endpoints_controller.go, pkg/libs/endpointaccessible/endpoint_accessible_controller.go
Adds injectable proxy functions to custom route availability checks and endpoint accessibility controllers, and wires them through OAuth route checking.
Proxy validation
pkg/controllers/proxyconfig/proxyconfig_controller.go, pkg/controllers/proxyconfig/proxyconfig_controller_test.go
Reworks proxy validation to use component-scoped settings first, then cluster proxy settings, and adds IdP reachability checks with warning events.
Operator wiring
pkg/operator/starter.go
Updates controller startup wiring to pass the new listers, informers, and feature-gate accessor.

Estimated code review effort: 4 (Complex) | ~75 minutes


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error New logs emit IdP/token endpoint URLs and proxy URLs (e.g. hostnames), which can expose internal/customer endpoints. Redact URLs/hosts in these klog messages; log only generic failures or sanitized hostnames, and never print full proxy URLs or endpoint strings.
✅ Passed checks (14 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed All added/changed test titles are static literals; no dynamic names, timestamps, IPs, or generated identifiers were introduced.
Test Structure And Quality ✅ Passed No Ginkgo specs were added; the new tests are plain testing unit tests with temp dirs/deferred server cleanup and no Eventually/cluster waits.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests were added; the changed tests are unit tests and contain no MicroShift-unsupported APIs, tags, or missing guards.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Only a unit test file was touched; it contains Test_* functions with no Ginkgo e2e blocks or multi-node/SNO assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed PASS: the actual diff is test-only (idp_conversions_test.go); no pod specs, replicas, affinities, tolerations, or topology-specific scheduling changes were added.
Ote Binary Stdout Contract ✅ Passed No changed file adds main/TestMain/init/BeforeSuite hooks or stdout-printing calls; the PR only touches controller/library code and ordinary tests.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the new tests are unit tests and don’t require public internet access.
No-Weak-Crypto ✅ Passed Changed files use stdlib sha256/sha512 only; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or secret/token comparisons found.
Container-Privileges ✅ Passed The PR commit only changes a Go test file, and that file contains no privileged/host* or allowPrivilegeEscalation settings.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding support for a component-scoped proxy.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign atiratree for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@tchap
tchap force-pushed the disconnected-env-review branch 2 times, most recently from 834349a to 82ce053 Compare July 7, 2026 15:46

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
pkg/controllers/configobservation/oauth/observe_idps.go (1)

57-82: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add test coverage for the component-proxy transport branch.

The new component-scoped proxy resolution and CA-loading logic (lines 61-78) that swaps buildTransport to transport.TransportForCARefWithProxy isn't exercised by any test in this batch. This is the most complex new logic in the cohort and currently only has a default/no-proxy path tested (via idp_conversions_test.go).

Want me to draft a test for ObserveIdentityProviders covering: authProxy present with valid TrustedCA, authProxy present with missing/unreadable TrustedCA configmap, and GetComponentProxyConfig returning an error?

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controllers/configobservation/oauth/observe_idps.go` around lines 57 -
82, Add test coverage for the component-proxy branch in
ObserveIdentityProviders, since the new authProxy path that replaces
buildTransport with TransportForCARefWithProxy is not exercised yet. Add cases
around observeIdentityProviders/ObserveIdentityProviders that cover authProxy
being present with a valid TrustedCA ConfigMap, authProxy present but the
TrustedCA ConfigMap missing or unreadable, and GetComponentProxyConfig returning
an error. Verify the buildTransport closure uses the proxy values and CA data
when authProxy is available, and that the fallback/default transport path is
retained when proxy config lookup fails.
pkg/controllers/proxyconfig/proxyconfig_controller.go (1)

166-172: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Component proxy TrustedCA changes aren't watched.

Unlike the static caConfigMaps (filtered informers), the component-proxy's TrustedCA.Name configmap is resolved dynamically and isn't registered for change notifications — updates to it will only be picked up on the 60-minute periodic resync.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controllers/proxyconfig/proxyconfig_controller.go` around lines 166 -
172, The component proxy TrustedCA lookup in the proxy config controller is only
fetched on resync and is not watched for updates. Update the proxyconfig
controller logic around the TrustedCA handling in proxyconfig_controller.go so
the configmap referenced by authProxy.TrustedCA.Name is registered for change
notifications through the existing informer/filtering path, similar to how
caConfigMaps are tracked, and ensure the reconcile flow in the proxyconfig
controller reacts when that configmap changes.
pkg/controllers/proxyconfig/proxyconfig_controller_test.go (1)

244-353: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Consider adding a test for the hash-caching skip path.

Coverage here validates the reachability/warning-event behavior well, but there's no test exercising repeated calls with identical config to confirm the caching short-circuit (hash == p.lastIdPValidationHash) behaves as intended — this ties into the caching-design question raised in proxyconfig_controller.go.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controllers/proxyconfig/proxyconfig_controller_test.go` around lines 244
- 353, Add a test that exercises the hash-caching short-circuit in
validateIdPConnectivity, since Test_validateIdPConnectivity currently only
covers reachability and warning events. Reuse proxyConfigChecker and its
validateIdPConnectivity method with the same OAuth/IdentityProvider input twice,
then assert the second call hits the skip path when hash matches
p.lastIdPValidationHash and does not re-emit events or repeat validation work.
Use the existing test helpers like workingHTTPRoundTripper,
faultyHTTPRoundTripper, and the in-memory recorder to keep the case aligned with
the current test structure.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@go.mod`:
- Around line 145-147: Remove the personal-fork replace override from go.mod:
the current replace for github.com/openshift/api pointing to
github.com/tchap/api should not remain in the merged branch. Update the module
definition so github.com/openshift/api resolves to the upstream dependency
again, and keep any temporary branch-only override out of the final manifest.
Use the replace directive and github.com/openshift/api entry as the identifiers
to locate and delete the temporary fork reference.

---

Nitpick comments:
In `@pkg/controllers/configobservation/oauth/observe_idps.go`:
- Around line 57-82: Add test coverage for the component-proxy branch in
ObserveIdentityProviders, since the new authProxy path that replaces
buildTransport with TransportForCARefWithProxy is not exercised yet. Add cases
around observeIdentityProviders/ObserveIdentityProviders that cover authProxy
being present with a valid TrustedCA ConfigMap, authProxy present but the
TrustedCA ConfigMap missing or unreadable, and GetComponentProxyConfig returning
an error. Verify the buildTransport closure uses the proxy values and CA data
when authProxy is available, and that the fallback/default transport path is
retained when proxy config lookup fails.

In `@pkg/controllers/proxyconfig/proxyconfig_controller_test.go`:
- Around line 244-353: Add a test that exercises the hash-caching short-circuit
in validateIdPConnectivity, since Test_validateIdPConnectivity currently only
covers reachability and warning events. Reuse proxyConfigChecker and its
validateIdPConnectivity method with the same OAuth/IdentityProvider input twice,
then assert the second call hits the skip path when hash matches
p.lastIdPValidationHash and does not re-emit events or repeat validation work.
Use the existing test helpers like workingHTTPRoundTripper,
faultyHTTPRoundTripper, and the in-memory recorder to keep the case aligned with
the current test structure.

In `@pkg/controllers/proxyconfig/proxyconfig_controller.go`:
- Around line 166-172: The component proxy TrustedCA lookup in the proxy config
controller is only fetched on resync and is not watched for updates. Update the
proxyconfig controller logic around the TrustedCA handling in
proxyconfig_controller.go so the configmap referenced by
authProxy.TrustedCA.Name is registered for change notifications through the
existing informer/filtering path, similar to how caConfigMaps are tracked, and
ensure the reconcile flow in the proxyconfig controller reacts when that
configmap changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 2b46b993-e90b-4627-906c-fc961b3829e3

📥 Commits

Reviewing files that changed from the base of the PR and between 13a773d and 82ce053.

⛔ Files ignored due to path filters (32)
  • go.sum is excluded by !**/*.sum
  • vendor/github.com/openshift/api/config/v1/register.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_cluster_version.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_crio_credential_provider_config.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/types_infrastructure.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/config/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.model_name.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/config/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/features.md is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/features/features.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_authentication.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_csi_cluster_driver.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/types_ingresscontroller.go is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_authentication_01_authentications-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_csi-driver_01_clustercsidrivers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-CustomNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-Default.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-DevPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-OKD.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.crd-manifests/0000_50_ingress_00_ingresscontrollers-TechPreviewNoUpgrade.crd.yaml is excluded by !**/vendor/**, !vendor/**
  • vendor/github.com/openshift/api/operator/v1/zz_generated.deepcopy.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/zz_generated.featuregated-crd-manifests.yaml is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/zz_generated.model_name.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/github.com/openshift/api/operator/v1/zz_generated.swagger_doc_generated.go is excluded by !**/vendor/**, !vendor/**, !**/zz_generated*
  • vendor/modules.txt is excluded by !**/vendor/**, !vendor/**
📒 Files selected for processing (18)
  • go.mod
  • pkg/controllers/common/proxy.go
  • pkg/controllers/common/proxy_test.go
  • pkg/controllers/configobservation/configobservercontroller/observe_config_controller.go
  • pkg/controllers/configobservation/interfaces.go
  • pkg/controllers/configobservation/oauth/idp_conversions.go
  • pkg/controllers/configobservation/oauth/idp_conversions_test.go
  • pkg/controllers/configobservation/oauth/observe_idps.go
  • pkg/controllers/customroute/custom_route_conditions.go
  • pkg/controllers/customroute/custom_route_controller.go
  • pkg/controllers/deployment/default_deployment.go
  • pkg/controllers/deployment/deployment_controller.go
  • pkg/controllers/oauthendpoints/oauth_endpoints_controller.go
  • pkg/controllers/proxyconfig/proxyconfig_controller.go
  • pkg/controllers/proxyconfig/proxyconfig_controller_test.go
  • pkg/libs/endpointaccessible/endpoint_accessible_controller.go
  • pkg/operator/starter.go
  • pkg/transport/transport.go

Comment thread go.mod Outdated
@tchap
tchap force-pushed the disconnected-env-review branch 3 times, most recently from 26d4cf7 to c1080cc Compare July 7, 2026 16:07

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
pkg/controllers/proxyconfig/proxyconfig_controller.go (1)

174-174: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Optional: set MinVersion on this outbound TLS config.

Same as the customroute check — this client reaches the route /healthz (and, via clientWithProxy, external IdP endpoints in validateIdPConnectivity). The Go client default is TLS 1.2, so no live risk, but pinning MinVersion documents intent for these outbound calls.

🔒 Suggested change
-	tlsConfig := &tls.Config{RootCAs: caPool}
+	tlsConfig := &tls.Config{MinVersion: tls.VersionTLS12, RootCAs: caPool}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controllers/proxyconfig/proxyconfig_controller.go` at line 174, The
outbound TLS config in the proxy config controller should explicitly pin a
minimum TLS version for these client connections. Update the tls.Config
initialization in the proxy setup path (the tlsConfig used with clientWithProxy
and the /healthz / validateIdPConnectivity calls) to set MinVersion consistently
with the other outbound TLS checks so the intent is documented and enforced.

Source: Linters/SAST tools

pkg/controllers/customroute/custom_route_conditions.go (1)

166-168: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low value

Optional: set MinVersion on the TLS config.

Static analysis flags a missing MinVersion. The Go client default is already TLS 1.2, so this is not a live vulnerability, but pinning it makes the intent explicit for this outbound check.

🔒 Suggested change
 			TLSClientConfig: &tls.Config{
+				MinVersion: tls.VersionTLS12,
 				RootCAs: rootCAs,
 			},
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@pkg/controllers/customroute/custom_route_conditions.go` around lines 166 -
168, The TLS config in custom route outbound check currently only sets RootCAs
and leaves the minimum protocol version implicit. Update the tls.Config used in
this client setup to explicitly set MinVersion in the same TLSClientConfig
block, using the existing configuration path around the outbound check so the
intent is clear in the code.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@pkg/controllers/customroute/custom_route_conditions.go`:
- Around line 166-168: The TLS config in custom route outbound check currently
only sets RootCAs and leaves the minimum protocol version implicit. Update the
tls.Config used in this client setup to explicitly set MinVersion in the same
TLSClientConfig block, using the existing configuration path around the outbound
check so the intent is clear in the code.

In `@pkg/controllers/proxyconfig/proxyconfig_controller.go`:
- Line 174: The outbound TLS config in the proxy config controller should
explicitly pin a minimum TLS version for these client connections. Update the
tls.Config initialization in the proxy setup path (the tlsConfig used with
clientWithProxy and the /healthz / validateIdPConnectivity calls) to set
MinVersion consistently with the other outbound TLS checks so the intent is
documented and enforced.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: openshift/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 6648ea73-99c6-4c00-85df-d8165bf94bf5

📥 Commits

Reviewing files that changed from the base of the PR and between 82ce053 and 40ad393.

📒 Files selected for processing (17)
  • pkg/controllers/common/proxy.go
  • pkg/controllers/common/proxy_test.go
  • pkg/controllers/configobservation/configobservercontroller/observe_config_controller.go
  • pkg/controllers/configobservation/interfaces.go
  • pkg/controllers/configobservation/oauth/idp_conversions.go
  • pkg/controllers/configobservation/oauth/idp_conversions_test.go
  • pkg/controllers/configobservation/oauth/observe_idps.go
  • pkg/controllers/customroute/custom_route_conditions.go
  • pkg/controllers/customroute/custom_route_controller.go
  • pkg/controllers/deployment/default_deployment.go
  • pkg/controllers/deployment/deployment_controller.go
  • pkg/controllers/oauthendpoints/oauth_endpoints_controller.go
  • pkg/controllers/proxyconfig/proxyconfig_controller.go
  • pkg/controllers/proxyconfig/proxyconfig_controller_test.go
  • pkg/libs/endpointaccessible/endpoint_accessible_controller.go
  • pkg/operator/starter.go
  • pkg/transport/transport.go
🚧 Files skipped from review as they are similar to previous changes (15)
  • pkg/controllers/configobservation/configobservercontroller/observe_config_controller.go
  • pkg/controllers/configobservation/interfaces.go
  • pkg/controllers/oauthendpoints/oauth_endpoints_controller.go
  • pkg/controllers/customroute/custom_route_controller.go
  • pkg/controllers/common/proxy_test.go
  • pkg/controllers/configobservation/oauth/observe_idps.go
  • pkg/libs/endpointaccessible/endpoint_accessible_controller.go
  • pkg/controllers/configobservation/oauth/idp_conversions_test.go
  • pkg/operator/starter.go
  • pkg/controllers/common/proxy.go
  • pkg/controllers/deployment/default_deployment.go
  • pkg/transport/transport.go
  • pkg/controllers/configobservation/oauth/idp_conversions.go
  • pkg/controllers/deployment/deployment_controller.go
  • pkg/controllers/proxyconfig/proxyconfig_controller_test.go

@tchap
tchap force-pushed the disconnected-env-review branch 15 times, most recently from c81c38f to 4078eb9 Compare July 9, 2026 14:20
@tchap
tchap force-pushed the disconnected-env-review branch 2 times, most recently from ed6c4f4 to d40b027 Compare July 14, 2026 14:40
@tchap
tchap marked this pull request as ready for review July 14, 2026 14:49
@openshift-ci
openshift-ci Bot requested review from flavianmissi and xueqzhan July 14, 2026 14:51
@tchap
tchap force-pushed the disconnected-env-review branch from d40b027 to 9a170f7 Compare July 15, 2026 09:59

@ehearne-redhat ehearne-redhat left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overall things look good - another concern that I cannot pinpoint here is if there is a mechanism we can use to interact with oauth-server to ensure that it "does what it says on the tin" i.e. hot reload.

Maybe not something we can effectively do yet until the oauth-server logic is implemented, but definitely something to note. :)

"time"

"github.com/openshift/library-go/pkg/crypto"
"github.com/stretchr/testify/require"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

I'm wondering if we should follow assertions instead of relying on an external dependency to save a few lines of code. Especially since the other test files you have created don't use this convention.

I'm thinking we should remove this to keep things consistent. If we need to write the additional lines for clarity, that should be okay. :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I was not paying extra attention to the library being used, but it's not a new dependency and it's being used across the code base, so I would not worry too much about it.

But the import block is badly formatted 🥲

Comment thread pkg/transport/transport_test.go Outdated
@tchap

tchap commented Jul 15, 2026

Copy link
Copy Markdown
Author

Overall things look good - another concern that I cannot pinpoint here is if there is a mechanism we can use to interact with oauth-server to ensure that it "does what it says on the tin" i.e. hot reload.

Maybe not something we can effectively do yet until the oauth-server logic is implemented, but definitely something to note. :)

Yeah, and this must be handled in e2e tests.

@tchap
tchap force-pushed the disconnected-env-review branch 2 times, most recently from 63e56f6 to 21d380d Compare July 15, 2026 11:02
tchap added 5 commits July 21, 2026 12:27
Add TransportForCARefWithProxy for building proxy-aware
transports with optional extra CA data.
Add shared utilities for component-scoped proxy configuration:

- ResolveProxy: reads spec.proxy from the Authentication operator CR
  when the AuthenticationComponentProxy feature gate is enabled and
  returns a ResolvedProxy with the effective proxy strings, falling
  back to the process environment when no component proxy is configured.
- ResolvedProxy.ProxyFunc: returns a func(*http.Request) (*url.URL, error)
  suitable for http.Transport.Proxy.
Wire the component-scoped proxy into every affected controller:

Config observer: builds a proxy-aware HTTP transport for OIDC
discovery and password grant checks. The Listers struct gains
OperatorAuthLister and FeatureGateAccessor. The convertIdentityProviders
signature changes from a ConfigMap lister to a transportForCABuilderFunc,
decoupling transport construction from the IDP conversion logic. Adds an
ObserveProxyTrustedCA observer that injects the proxy CA bundle path into
the observed config when a component proxy with a trustedCA is active.

Deployment controller: resolves the component proxy, injects
HTTP_PROXY/HTTPS_PROXY/NO_PROXY env vars into the OAuth Server pod,
syncs the trustedCA ConfigMap from openshift-config to
openshift-authentication, and adds a volume/mount with Optional=true
for CA hot-reload without redeployment.

Proxy validation controller: validates route reachability through
the component proxy. Tests IdP endpoint connectivity and emits
IdPEndpointUnreachable Warning events for transient failures
(does not set Degraded). Uses hash-based change detection to
avoid redundant validation.

Endpoint accessible controller: gains an optional proxy function
for route health checks. Only the route check controller gets the
proxy because it connects to the external route hostname; service
and endpoint checks connect to cluster-internal addresses and
remain proxy-free.

Custom route controller: resolves the component proxy via
ResolveProxy for the route availability health check. Loads the
proxy trusted CA via LoadCAData and appends it to the root CA pool.
Fixes the routeAvailablity typo (now routeAvailability).

Operator startup: passes operatorAuthLister, featureGateAccessor,
and operatorAuthInformer to all affected controllers.
Extract shared test helpers into pkg/internal/transporttest:
UnwrapTransport, MakeSelfSignedCA, MustParseURL. Replace local
copies in transport, proxy, and observe_idps test files.

Add TestBuildIDPTransport to verify that with the feature gate
enabled and a component proxy with trusted CA configured, the
IDP transport builder wires the proxy function and loads the CA.

Add Test_validateIdPConnectivity_hashDedup to verify hash-based
dedup: successful validation saves the hash and skips redundant
checks; failed validation does not save the hash, allowing retry.

Enable the AuthenticationComponentProxy feature gate in
TestObserveIdentityProviders to exercise the gate-enabled path
with no proxy configured (no-op fallback to environment).
@tchap
tchap force-pushed the disconnected-env-review branch from 5cb7b08 to ccddfe3 Compare July 21, 2026 10:28
@tchap

tchap commented Jul 22, 2026

Copy link
Copy Markdown
Author

/retitle CNTRLPLANE-3762: Add support for component-scoped proxy

We are gonna merge this without e2e tests.

@openshift-ci openshift-ci Bot changed the title WIP: CNTRLPLANE-3762: Add support for component-scoped proxy CNTRLPLANE-3762: Add support for component-scoped proxy Jul 22, 2026
@tchap

tchap commented Jul 22, 2026

Copy link
Copy Markdown
Author

/retest

@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 22, 2026

@everettraven everettraven left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Leaving the review I've gotten to so far.

There is much more to try and connect here than I had initially thought. I'm going to try and step through the changes a bit more intentionally tomorrow morning with a fresh set of eyes.

Comment thread pkg/controllers/common/proxy.go Outdated
Comment thread pkg/controllers/common/proxy_test.go Outdated
Comment thread pkg/controllers/common/proxy_test.go Outdated
tchap added 2 commits July 23, 2026 11:51
Use sets.List() instead of sets.UnsortedList() to produce sorted,
deterministic noProxy values and prevent oauth-server deployment churn.
Remove the now-unnecessary sortedCSV test helper and the standalone
TestResolveProxy_FeatureGateError that duplicated a table-driven case.
The OAuthServerRouteEndpointAccessibleController checks the OAuth
route health through the proxy. When the proxy uses TLS (https://),
the controller needs the proxy's trustedCA in its root CA pool.

Use ResolveProxy to get the TrustedCAName, then load the CA from
the source ConfigMap in openshift-config via transport.LoadCAData
— consistent with how ProxyConfigController loads it.
Comment on lines +35 to +39
// ResolveProxy reads the component-scoped proxy from the Authentication
// operator CR (when the feature gate is enabled) and returns the effective proxy
// settings. When no component proxy is configured, it falls back to the process
// environment (which reflects the cluster-wide proxy).
func ResolveProxy(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Having gone through a lot of the code changes here, I wonder if making this a struct that contains a method equivalent to this ResolveProxy function would be a better path that reduces the amount of changes a bit further?

As an example, as part of the external OIDC work, we added

type AuthConfigChecker struct {
authenticationsInformer cache.SharedIndexInformer
kubeAPIServersInformer cache.SharedIndexInformer
kasNamespaceConfigMapsInformer cache.SharedIndexInformer
oaasNamespaceConfigMapsInformer cache.SharedIndexInformer
authLister configv1listers.AuthenticationLister
kasLister operatorv1listers.KubeAPIServerLister
kasConfigMapLister corelistersv1.ConfigMapLister
oaasConfigMapLister corelistersv1.ConfigMapLister
featureGateAccessor featuregates.FeatureGateAccess
}
func NewAuthConfigChecker(authentications configv1informers.AuthenticationInformer, kubeapiservers operatorv1informers.KubeAPIServerInformer, kasConfigMaps, oaasConfigMaps corev1informers.ConfigMapInformer, featureGateAccessor featuregates.FeatureGateAccess) AuthConfigChecker {
return AuthConfigChecker{
authenticationsInformer: authentications.Informer(),
kubeAPIServersInformer: kubeapiservers.Informer(),
kasNamespaceConfigMapsInformer: kasConfigMaps.Informer(),
oaasNamespaceConfigMapsInformer: oaasConfigMaps.Informer(),
authLister: authentications.Lister(),
kasLister: kubeapiservers.Lister(),
kasConfigMapLister: kasConfigMaps.Lister(),
oaasConfigMapLister: oaasConfigMaps.Lister(),
featureGateAccessor: featureGateAccessor,
}
}

Which allowed us to minimally change function signatures to accept that new struct (or an interface that struct satisfies - which is my preference for mocking in unit tests) and avoid having to make changes to things like the listers struct to add the feature gate accessor. Instead, we instantiate it once in starter.go like

authConfigChecker := common.NewAuthConfigChecker(
informerFactories.operatorConfigInformer.Config().V1().Authentications(),
informerFactories.operatorInformer.Operator().V1().KubeAPIServers(),
informerFactories.kubeInformersForNamespaces.InformersFor("openshift-kube-apiserver").Core().V1().ConfigMaps(),
informerFactories.kubeInformersForNamespaces.InformersFor("openshift-oauth-apiserver").Core().V1().ConfigMaps(),
featureGateAccessor,
)
and pass it to the things that need it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I will look into this probably when I finish some of the e2e tests, too much context switching.

I agree this would be nice. I probably ended up with the messy approach because I was implementing things gradually and didn't get to the final refactoring.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I refactored the changes in dbef886

Comment on lines +24 to +26
// transportForCABuilderFunc builds an http.RoundTripper for a given CA ConfigMap
// reference. The cmLister and any proxy settings are captured in the closure.
type transportForCABuilderFunc func(caConfigMapName, key string) (http.RoundTripper, error)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Is there a particular reason why this transport builder function needs to be scoped specifically to this configobserver?

I had anticipated that we would probably want a more generic transport builder implementation that things call out to to get the HTTP transport configuration / roundtripper needed for the client.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

The IDP observer is special because it needs to merge the IdP CA with the proxy CA, whereas other call sites only need the proxy CA directly. But I agree the builder pattern could be generalized.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

I refactored the changes in dbef886

tchap added 2 commits July 23, 2026 19:50
Go's in-cluster client connects to the kube API by raw IP (from
KUBERNETES_SERVICE_HOST env var), not by hostname, so the existing
.svc and .cluster.local entries do not exclude it from proxy routing.
Add the IP explicitly so oauth-openshift pods don't route kube API
calls through the component proxy.
Introduce ProxyResolver interface and AuthProxyResolver implementation
that encapsulate proxy resolution, proxy CA loading, and HTTP transport
construction. This follows the AuthConfigChecker pattern: instantiated
once in starter.go and passed to controllers via interface.

Controllers no longer store featureGateAccessor and operatorAuthLister
fields just for proxy resolution, and no longer manually load proxy CA
or construct http.Transport without knet.SetTransportDefaults.

NewTransport accepts functional options (WithCA for raw bytes,
WithCAFromConfigMap for ConfigMap references) so callers declare what
CA trust they need without knowing how it's fetched.

Removes the transportForCABuilderFunc type, buildIDPTransport function,
and the now-unused TransportForCARef/CAReference from pkg/transport —
IDP conversions and all other callers now use ProxyResolver directly.
@tchap
tchap force-pushed the disconnected-env-review branch from e9fd692 to dbef886 Compare July 27, 2026 07:45
@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

@tchap: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants