Skip to content

Endpoints write permissions removed in OCP 4.21#642

Merged
mnovak merged 2 commits into
xtf-cz:mainfrom
kanovotn:endpoints
Apr 16, 2026
Merged

Endpoints write permissions removed in OCP 4.21#642
mnovak merged 2 commits into
xtf-cz:mainfrom
kanovotn:endpoints

Conversation

@kanovotn
Copy link
Copy Markdown
Contributor

@kanovotn kanovotn commented Apr 2, 2026

This is related to [#639].

This is related to CVE-2021-25740 . XTF's OpenShift.clean() calls endpoints().delete() and endpoints().list(), which require Endpoints write/read permissions. On OCP 4.21, users with the standard edit or admin role no longer have Endpoints write access, causing a 403 KubernetesClientException that aborts the entire cleanup - leaving services, pods, routes, and everything after the endpoints call uncleaned.

Why do we see it now:

Even this change was implemented in Kubernetes 1.22, we see the it first time in OCP 4.21 (Kubernetes 1.34) because until OCP 4.20, Openshift was reverting this with each release, because this issue was evaluated by RedHat as not affected. Recently it was removed from list of patches applied with each OCP release.

What has been changed

The endpoints() call in Openshift.clean() and listRemovableResources().
This endpoints are managed by Service resource.

Openshift.createEndpoint and Openshift.deleteEndpoint()
They will work only when user with edit role on Endpoints is used - Write access for endpoints

Deprecated EndpointBuilder
Endpoints were deprecated in Kubernetes v1.33.

OpenshiftApplication

  • Removes the wiring on Endpoints which was anyway not packed into the application.

Links
CVE-2021-25740: Endpoint & EndpointSlice permissions allow cross-Namespace forwarding · Issue #103675 · kubernetes/kubernetes

Using RBAC Authorization

1982470 – (CVE-2021-25740) CVE-2021-25740 kubernetes: Endpoint & EndpointSlice permissions allow cross-Namespace forwarding

Revert "Remove Endpoints write access from aggregated edit role" by danwinship · Pull Request #908 · openshift/kubernetes

Summary by Sourcery

Adjust OpenShift cleanup and application wiring to avoid relying on Endpoints resources that now require elevated permissions, and mark legacy Endpoints usage as deprecated in favor of EndpointSlice.

Bug Fixes:

  • Prevent OpenShift.clean() and listRemovableResources() from failing when Endpoints write access is not available by no longer including Endpoints in the default cleanup/removal flow.

Enhancements:

  • Document that createEndpoint and deleteEndpoint require roles with Endpoints write permissions.
  • Deprecate EndpointBuilder in favor of EndpointSlice to align with Kubernetes deprecation of Endpoints.
  • Remove Endpoints from OpenShiftApplication resource wiring since they were not effectively part of the packaged application.

@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 2, 2026

Reviewer's Guide

Adjusts OpenShift cleanup and application-building logic to stop managing Endpoints (which now require stricter RBAC and are deprecated), documents permission requirements on remaining endpoint helpers, and deprecates the EndpointBuilder API.

Sequence diagram for updated OpenShift.clean without Endpoints deletion

sequenceDiagram
    participant TestCode
    participant OpenShift
    participant KubernetesAPI

    TestCode->>OpenShift: clean()
    activate OpenShift

    OpenShift->>KubernetesAPI: replicationControllers().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    OpenShift->>KubernetesAPI: buildConfigs().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    OpenShift->>KubernetesAPI: imageStreams().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    Note over OpenShift,KubernetesAPI: No call to endpoints().withLabelNotIn(...).delete()

    OpenShift->>KubernetesAPI: services().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    OpenShift->>KubernetesAPI: builds().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    OpenShift->>KubernetesAPI: routes().withLabelNotIn(...).delete()
    KubernetesAPI-->>OpenShift: deletion result

    OpenShift-->>TestCode: Waiter
    deactivate OpenShift
Loading

Class diagram for updated OpenShift, OpenShiftApplication, and EndpointBuilder

classDiagram
    class OpenShift {
        +Waiter clean()
        +List~HasMetadata~ listRemovableResources()
        +Endpoints createEndpoint(Endpoints endpoint)
        +List~Endpoints~ getEndpoints()
        +boolean deleteEndpoint(Endpoints endpoint)
        +boolean deleteService(Service service)
    }

    class OpenShiftApplication {
        -OpenShift openShift
        -List~PersistentVolumeClaim~ persistentVolumeClaims
        -List~DeploymentConfig~ deploymentConfigs
        -List~Service~ services
        -List~Route~ routes
        -List~ConfigMap~ configMaps
        -List~HorizontalPodAutoscaler~ autoScalers
        -List~ImageStream~ imageStreams
        -List~BuildConfig~ buildConfigs
        -List~Build~ builds
        -List~RoleBinding~ roleBindings
        -List~ServiceAccount~ serviceAccounts
        -List~Secret~ secrets
        -List~PodSecurityPolicy~ podSecurityPolicies
        -List~ClusterRole~ clusterRoles
        -List~ClusterRoleBinding~ clusterRoleBindings
        -List~ImageStreamTag~ imageStreamTags
        -List~Template~ templates
        -List~ProjectRequest~ projectRequests
        -List~Namespace~ namespaces
        -List~LimitRange~ limitRanges
        -List~ResourceQuota~ resourceQuotas
        -List~NetworkPolicy~ networkPolicies
        -List~PodDisruptionBudget~ podDisruptionBudgets
        -List~Job~ jobs
        -List~CronJob~ cronJobs
        -List~DaemonSet~ daemonSets
        -List~StatefulSet~ statefulSets
        -List~ServiceMonitor~ serviceMonitors
        -List~Alertmanager~ alertmanagers
        -List~Prometheus~ prometheuses
        -List~Route~ routes
        -void createResources()
    }

    class EndpointBuilder {
        <<deprecated>>
        -List~String~ endpointIPs
        -List~Port~ ports
        +EndpointBuilder addIp(String ip)
        +EndpointBuilder addPort(Port port)
        +Endpoints build()
    }

    class AbstractBuilder~T, B~ {
        +B withName(String name)
        +B addLabel(String key, String value)
        +T build()
    }

    class Endpoints
    class Service
    class Route

    EndpointBuilder --|> AbstractBuilder~Endpoints, EndpointBuilder~

    OpenShiftApplication o--> OpenShift : uses
    OpenShiftApplication o--> Service
    OpenShiftApplication o--> Route
    OpenShiftApplication o--> DeploymentConfig
    OpenShiftApplication o--> PersistentVolumeClaim

    OpenShift --> Endpoints : create/delete
    OpenShift --> Service : deleteService
Loading

File-Level Changes

Change Details Files
Stop deleting/listing Endpoints as part of OpenShift namespace cleanup to avoid RBAC failures on newer OCP versions.
  • Remove endpoints deletion call from OpenShift.clean() so cleanup no longer requires Endpoints write permissions.
  • Remove endpoints listing from OpenShift.listRemovableResources() so the removable-set computation does not depend on Endpoints access.
core/src/main/java/cz/xtf/core/openshift/OpenShift.java
Document RBAC requirements for endpoint helper methods in the OpenShift client.
  • Add JavaDoc to createEndpoint to state that a role with Endpoints write permissions is required and link to upstream RBAC docs.
  • Add JavaDoc to deleteEndpoint to state that a role with Endpoints write permissions is required and link to upstream RBAC docs.
core/src/main/java/cz/xtf/core/openshift/OpenShift.java
Deprecate EndpointBuilder and remove Endpoint wiring from OpenShiftApplication to reflect Endpoints deprecation and reduced management scope.
  • Mark EndpointBuilder as deprecated with version notes, reference to EndpointSlice, and link to RBAC/endpoints docs.
  • Remove the endpoints list field from OpenShiftApplication so applications no longer track Endpoints as a managed resource type.
  • Remove the creation/wiring of endpoints in OpenShiftApplication.createResources() so application deployment no longer creates Endpoints via the OpenShift client.
builder/src/main/java/cz/xtf/builder/builders/EndpointBuilder.java
builder/src/main/java/cz/xtf/builder/OpenShiftApplication.java

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@kanovotn kanovotn marked this pull request as ready for review April 7, 2026 11:18
Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

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

Hey - I've found 1 issue, and left some high level feedback:

  • Since EndpointBuilder is now deprecated in the Javadoc, consider also adding the @Deprecated annotation on the class to ensure tooling and callers are properly warned at compile time.
  • For createEndpoint and deleteEndpoint, now that the Javadoc explicitly calls out the need for write permissions, it may be helpful to document (or standardize) what exception is thrown on 403 responses so callers can reliably handle the permission failure case.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Since `EndpointBuilder` is now deprecated in the Javadoc, consider also adding the `@Deprecated` annotation on the class to ensure tooling and callers are properly warned at compile time.
- For `createEndpoint` and `deleteEndpoint`, now that the Javadoc explicitly calls out the need for write permissions, it may be helpful to document (or standardize) what exception is thrown on 403 responses so callers can reliably handle the permission failure case.

## Individual Comments

### Comment 1
<location path="core/src/main/java/cz/xtf/core/openshift/OpenShift.java" line_range="684-686" />
<code_context>
+     * @param endpoint
+     * @return Endpoints created
+     */
     public Endpoints createEndpoint(Endpoints endpoint) {
         return endpoints().resource(endpoint).create();
     }
</code_context>
<issue_to_address>
**suggestion:** Consider deprecating the OpenShift endpoint helpers to align with EndpointBuilder and Kubernetes Endpoints deprecation.

Since EndpointBuilder and Kubernetes Endpoints are now deprecated, consider annotating `createEndpoint`/`deleteEndpoint` with `@Deprecated` and referencing the preferred alternative (e.g., EndpointSlice-based flows) so callers don’t add new usage of a phased-out API.

Suggested implementation:

```java
    // Endpoints
    /**
     * Needs a role with write permissions see
     * <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#write-access-for-endpoints">Endpoint write
     * access</a>
     *
     * @param endpoint
     * @return Endpoints created
     * @deprecated Use EndpointSlice-based flows instead of Endpoints. This helper is deprecated to align with
     *             {@code EndpointBuilder} and Kubernetes {@code Endpoints} deprecation.
     */
    @Deprecated
    public Endpoints createEndpoint(Endpoints endpoint) {
        return endpoints().resource(endpoint).create();
    }

```

You should similarly deprecate the `deleteEndpoint` helper in the same class. For the `deleteEndpoint` method:

1. Add a Javadoc `@deprecated` tag explaining that callers should migrate to EndpointSlice-based flows (and, if you have a specific replacement API in this project, reference it explicitly).
2. Add the `@Deprecated` annotation to the method declaration.

For example, if it currently looks like:
```java
    /**
     * Deletes an Endpoints resource.
     *
     * @param name name of the Endpoints resource
     */
    public void deleteEndpoint(String name) {
        endpoints().withName(name).delete();
    }
```
update it to:
```java
    /**
     * Deletes an Endpoints resource.
     *
     * @param name name of the Endpoints resource
     * @deprecated Use EndpointSlice-based flows instead of Endpoints. This helper is deprecated to align with
     *             {@code EndpointBuilder} and Kubernetes {@code Endpoints} deprecation.
     */
    @Deprecated
    public void deleteEndpoint(String name) {
        endpoints().withName(name).delete();
    }
```
Adjust the `SEARCH` portion of the edit block to match the exact existing Javadoc/method signature in your file.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines 684 to 686
public Endpoints createEndpoint(Endpoints endpoint) {
return endpoints().resource(endpoint).create();
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion: Consider deprecating the OpenShift endpoint helpers to align with EndpointBuilder and Kubernetes Endpoints deprecation.

Since EndpointBuilder and Kubernetes Endpoints are now deprecated, consider annotating createEndpoint/deleteEndpoint with @Deprecated and referencing the preferred alternative (e.g., EndpointSlice-based flows) so callers don’t add new usage of a phased-out API.

Suggested implementation:

    // Endpoints
    /**
     * Needs a role with write permissions see
     * <a href="https://kubernetes.io/docs/reference/access-authn-authz/rbac/#write-access-for-endpoints">Endpoint write
     * access</a>
     *
     * @param endpoint
     * @return Endpoints created
     * @deprecated Use EndpointSlice-based flows instead of Endpoints. This helper is deprecated to align with
     *             {@code EndpointBuilder} and Kubernetes {@code Endpoints} deprecation.
     */
    @Deprecated
    public Endpoints createEndpoint(Endpoints endpoint) {
        return endpoints().resource(endpoint).create();
    }

You should similarly deprecate the deleteEndpoint helper in the same class. For the deleteEndpoint method:

  1. Add a Javadoc @deprecated tag explaining that callers should migrate to EndpointSlice-based flows (and, if you have a specific replacement API in this project, reference it explicitly).
  2. Add the @Deprecated annotation to the method declaration.

For example, if it currently looks like:

    /**
     * Deletes an Endpoints resource.
     *
     * @param name name of the Endpoints resource
     */
    public void deleteEndpoint(String name) {
        endpoints().withName(name).delete();
    }

update it to:

    /**
     * Deletes an Endpoints resource.
     *
     * @param name name of the Endpoints resource
     * @deprecated Use EndpointSlice-based flows instead of Endpoints. This helper is deprecated to align with
     *             {@code EndpointBuilder} and Kubernetes {@code Endpoints} deprecation.
     */
    @Deprecated
    public void deleteEndpoint(String name) {
        endpoints().withName(name).delete();
    }

Adjust the SEARCH portion of the edit block to match the exact existing Javadoc/method signature in your file.

@mchoma
Copy link
Copy Markdown
Contributor

mchoma commented Apr 8, 2026

Can we have attached CI run confirming everything is still ok?

My understanding of change is we will be not explicitly deleting Endpoint objects. We are not creating Enpoint objects directly, but just through Service object. So once we delete Service, dependant Endpoints will be removed as well. Do I understand it correctly?

@mnovak
Copy link
Copy Markdown
Contributor

mnovak commented Apr 8, 2026

@liborfuka could you take a look at this PR as well please?

@liborfuka
Copy link
Copy Markdown
Contributor

It looks ok to me. Thank you @kanovotn for PR.
It fixes #639

@kanovotn
Copy link
Copy Markdown
Contributor Author

Can we have attached CI run confirming everything is still ok?

My understanding of change is we will be not explicitly deleting Endpoint objects. We are not creating Enpoint objects directly, but just through Service object. So once we delete Service, dependant Endpoints will be removed as well. Do I understand it correctly?

@mchoma Yes, that's correct.

Copy link
Copy Markdown
Contributor

@mchoma mchoma left a comment

Choose a reason for hiding this comment

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

Ok to merge this. Runs attached to https://redhat.atlassian.net/browse/EAPQE-5152

@mnovak mnovak merged commit 1a1bcae into xtf-cz:main Apr 16, 2026
6 checks passed
@mnovak
Copy link
Copy Markdown
Contributor

mnovak commented Apr 16, 2026

LGTM, merging. Thansk for the fix.

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.

4 participants