Skip to content

CNTRLPLANE-3378: enhancements/authentication: Add proxy support for integrated auth stack#2015

Open
tchap wants to merge 15 commits into
openshift:masterfrom
tchap:auth-proxy
Open

CNTRLPLANE-3378: enhancements/authentication: Add proxy support for integrated auth stack#2015
tchap wants to merge 15 commits into
openshift:masterfrom
tchap:auth-proxy

Conversation

@tchap
Copy link
Copy Markdown

@tchap tchap commented May 18, 2026

This enhancement adds an optional, component-scoped proxy configuration
to the Authentication operator (operator.openshift.io/v1) so that
authentication components (CAO, OAuth Server) can reach external identity
providers through a proxy without requiring the cluster-wide egress proxy.

@openshift-ci-robot
Copy link
Copy Markdown

openshift-ci-robot commented May 18, 2026

@tchap: This pull request references CNTRLPLANE-3378 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 enhancement adds an optional, component-scoped proxy configuration
to the Authentication operator (operator.openshift.io/v1) so that
authentication components (CAO, OAuth Server) can reach external identity
providers through a proxy without requiring the cluster-wide egress proxy.

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 May 18, 2026
@openshift-ci openshift-ci Bot requested review from flavianmissi and tremes May 18, 2026 19:29
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 18, 2026

[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 jmguzik 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 auth-proxy branch 3 times, most recently from 2704243 to dff70c3 Compare May 18, 2026 19:51
…roxy

Adds an optional proxy configuration to the Authentication operator
(operator.openshift.io/v1) so that authentication components can reach
external identity providers through a proxy without requiring the
cluster-wide egress proxy.
Copy link
Copy Markdown
Member

@liouk liouk left a comment

Choose a reason for hiding this comment

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

Looks good overall, I've added some comments.

Apart from these, there are a couple more considerations that I'd suggest we think about and add to the enhancement:

  • it is worth mentioning LDAP Group Sync; this is usually done as a CronJob, and while this is user-managed rather than operator-managed, it should be at least clear in documentation that in such a disconnected scenario, setting the auth proxy will not be enough for LDAP group sync to work.
  • the CAO makes endpoint accessibility checks which hit the external oauth route, so that will need proxy awareness as well; since the proxy isn't configured in the operator's env but rather read from the config, we'll need to set the endpoint checks' proxy appropriately.

Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Resolution follows three states:

1. `spec.proxy` set with non-empty values — use component-scoped proxy, overriding any cluster-wide proxy.
2. `spec.proxy` set with empty strings (`httpProxy: ""`, `httpsProxy: ""`) — explicitly no proxy for auth components, even if a cluster-wide proxy is configured.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am skeptical about the value of the "override cluster proxy with no proxy for auth" use-case. This implies auth has a direct route to the IDP while nothing else has direct egress, which is an unusual network topology.

Given this assumption I see why we choose *string over string for these fields, however if indeed there's no value to this use-case, we could simplify the API further by removing this particular flow.

Copy link
Copy Markdown
Author

@tchap tchap May 19, 2026

Choose a reason for hiding this comment

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

Yeah, I was hesitant regarding possible values for the proxy object. I was thinking that either

  • When the proxy object is set, httpProxy and httpsProxy are simply required. In that case it can be string.
  • Or allow for meaningful zero values, which must be set explicitly, though. In that case I would use *string and using an empty string would disable proxying. I am not sure this makes sense with respect to overwriting the cluster-wide proxy, but just considering the component-scoped proxy, does it ever make sense to have one of the values unset? If not, we can simply go with string and require both values.

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.

I share @liouk's skepticism on the use case for having the cluster-wide proxy configured but omitting auth components specifically. Instead, I'd expect any domains that shouldn't be proxied to be defined in the cluster-wide noProxy configuration.

I'm also not aware of any requests for behavior like this.

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.

Do you mean that we should inherit the noProxy field from the cluster-wide proxy when that is available?

Copy link
Copy Markdown
Member

@liouk liouk May 28, 2026

Choose a reason for hiding this comment

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

@everettraven @tchap unless I'm missing some use-case other than the IDP, I think what we need here is no inheritance from the cluster-wide proxy (CWP) at all when the auth proxy (AP) is set; we should just let the operator append the default noProxy (in-cluster) values and that's all.

Since setting the AP gets priority over the CWP, inheriting what the CWP sets might lead to a conflict. Imagine the CWP sets the IDP's domain in noProxy, and we also set an AP -- the AP takes precedence over the CWP, but noProxy dictates that calls to the IDP shouldn't be proxied.

@tchap
Copy link
Copy Markdown
Author

tchap commented May 19, 2026

  • it is worth mentioning LDAP Group Sync; this is usually done as a CronJob, and while this is user-managed rather than operator-managed, it should be at least clear in documentation that in such a disconnected scenario, setting the auth proxy will not be enough for LDAP group sync to work.

Added in a16c166

Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Resolution follows three states:

1. `spec.proxy` set with non-empty values — use component-scoped proxy, overriding any cluster-wide proxy.
2. `spec.proxy` set with empty strings (`httpProxy: ""`, `httpsProxy: ""`) — explicitly no proxy for auth components, even if a cluster-wide proxy is configured.
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.

I share @liouk's skepticism on the use case for having the cluster-wide proxy configured but omitting auth components specifically. Instead, I'd expect any domains that shouldn't be proxied to be defined in the cluster-wide noProxy configuration.

I'm also not aware of any requests for behavior like this.

Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
Comment thread enhancements/authentication/proxy-support-for-integrated-auth-stack.md Outdated
There were 2 separate sections. Now when adding endpoint accessiblity
details, this became too fragmented. So there is now one Operator
Process section with multiple bullet points for each component affected.
@tchap
Copy link
Copy Markdown
Author

tchap commented May 20, 2026

  • the CAO makes endpoint accessibility checks which hit the external oauth route, so that will need proxy awareness as well; since the proxy isn't configured in the operator's env but rather read from the config, we'll need to set the endpoint checks' proxy appropriately.

Added in c878755

tchap added 9 commits May 20, 2026 13:08
Add a table listing which controllers make outbound calls to external
IdP endpoints, covering both Integrated OAuth and External OIDC modes
with links to the relevant code locations.
Add code links to affected controllers with two-column format
(component + outbound call). Add custom route controller which
was missing from the list of controllers needing proxy awareness.
Add deployment controller to the affected list.
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 21, 2026

@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.

Copy link
Copy Markdown
Contributor

@everettraven everettraven left a comment

Choose a reason for hiding this comment

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

Only a handful of comments. Overall this looks pretty solid to me. Great work!

- "@everettraven"
creation-date: 2026-05-18
last-updated: 2026-05-21
status: provisional|implementable|implemented|deferred|rejected|withdrawn|replaced|informational
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.

implementable is probably a good choice at this point.

Comment on lines +195 to +196
// When omitted, the cluster-wide proxy is used, preserving
// existing behavior.
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.

We generally try to keep the GoDoc comments for APIs end-user focused and avoid leaking underlying component logic/behaviors that they won't care about. In this case, "preserving existing behavior" is likely ambiguous to an end user reading this so we should just be explicitly clear as to what the behavior here is:

Suggested change
// When omitted, the cluster-wide proxy is used, preserving
// existing behavior.
// When omitted, the cluster-wide proxy configuration is used.
// If the cluster-wide proxy is not configured, no proxy is used.

OperatorSpec `json:",inline"`

// proxy configures proxy settings for authentication components
// (the OAuth server and the cluster authentication operator).
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.

In the same vein of avoiding leaking of underlying architectural details, we can just remove the text within the parenthesis here:

Suggested change
// (the OAuth server and the cluster authentication operator).

Comment on lines +206 to +216
// httpProxy is the URL of the proxy for HTTP requests.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpProxy must be a valid URL"
// +optional
HTTPProxy string `json:"httpProxy,omitempty"`

// httpsProxy is the URL of the proxy for HTTPS requests.
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:XValidation:rule="isURL(self)",message="httpsProxy must be a valid URL"
// +optional
HTTPSProxy string `json:"httpsProxy,omitempty"`
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.

Both of these fields need a maximum length constraint to prevent the CEL rule from always assuming a worst-case string size for cost estimations.

For URLs I typically see 2048 characters being the limit here.

Also, isURL(self) parses this according to Golang's net/url.Parse() function that is pretty lenient in what a "valid URL" entails. For example, https:// parses as a valid URL.

We probably want some additional constraints enforced here for what would be considered a valid input. At the very least we probably want to ensure a scheme of http:// or https:// is specified and that there is a hostname.

Beyond that, I'd think about whether or not we should allow specifying the path, query parameters, fragments, and user info (I suspect we may want to allow user info since the cluster-wide proxy today does proxy authentication via the proxy url).

| Mode | Controller | Component | Outbound call |
|------|------------|-----------|---------------|
| Integrated OAuth | Config observation | [`ObserveIdentityProviders()`](https://github.com/openshift/cluster-authentication-operator/blob/9d5f19f8ad67/pkg/controllers/configobservation/oauth/observe_idps.go#L19) | [`discoverOpenIDURLs()`](https://github.com/openshift/cluster-authentication-operator/blob/9d5f19f8ad67/pkg/controllers/configobservation/oauth/idp_conversions.go#L315) |
| Integrated OAuth | Config observation | [`ObserveIdentityProviders()`](https://github.com/openshift/cluster-authentication-operator/blob/9d5f19f8ad67/pkg/controllers/configobservation/oauth/observe_idps.go#L19) | [`checkOIDCPasswordGrantFlow()`](https://github.com/openshift/cluster-authentication-operator/blob/9d5f19f8ad67/pkg/controllers/configobservation/oauth/idp_conversions.go#L373) |
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.

A bit of an aside, this is a weird way to determine if the provider supports the password grant flow.

If we are doing discovery, we could probably drop that in favor of basing off of the spec outlined in https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata but 🤷 .

I'm debating whether or not it would be worth it to change this behavior as part of this to reduce the areas we need to actually take the custom proxy into account. At the very least we should probably make some kind of tech debt item for us to track to take a look at this at some time in the future.

Comment on lines +479 to +490
## Test Plan

TBD

## Graduation Criteria

TBD

### Dev Preview -> Tech Preview

### Tech Preview -> GA

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.

We should fill these out with at least a high-level plan of how we are going to test the feature and determine whether it is ready to be promoted or not (outside of the standard requirements for all new features)


### Tech Preview -> GA

### Removing a deprecated feature
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.

Can add n/a for the text in this section since it doesn't actually apply to us here.

// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=253
// +required
Name string `json:"name"`
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.

I missed this in my last review, but this needs an omitempty tag.

We also want to add this CEL validation to ensure the correct input format for a ConfigMap name:

+kubebuilder:validation:XValidation:rule="!format.dns1123Subdomain().validate(self).hasValue()",message="name must be a valid DNS subdomain name: contain no more than 253 characters, contain only lowercase alphanumeric characters, '-' or '.', and start and end with an alphanumeric character"

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