Skip to content

ROSAENG-60641: Allow privileged service accounts to create NetworkPolicies in openshift-ingress#581

Merged
joshbranham merged 1 commit into
openshift:masterfrom
ugiordan:fix/networkpolicies-privileged-sa-openshift-ingress
Jun 29, 2026
Merged

ROSAENG-60641: Allow privileged service accounts to create NetworkPolicies in openshift-ingress#581
joshbranham merged 1 commit into
openshift:masterfrom
ugiordan:fix/networkpolicies-privileged-sa-openshift-ingress

Conversation

@ugiordan

@ugiordan ugiordan commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

Summary

OCP 4.22 introduced a deny-all NetworkPolicy (openshift-ingress-deny-all) in the openshift-ingress namespace via NE-2501. This requires operators that deploy pods into openshift-ingress to create explicit allow NetworkPolicies for their pods.

The current webhook logic has a special case for openshift-ingress that skips the privileged SA check entirely and only allows NPs whose podSelector contains ingresscontroller.operator.openshift.io/deployment-ingresscontroller with a non-default value. This blocks privileged service accounts (matching redhat-*, openshift-*, etc.) from creating NetworkPolicies for non-ingress-controller pods in that namespace.

The flow today:

  1. isAllowedNamespace("openshift-ingress") returns true (explicit carve-out on line 119)
  2. This skips the !isAllowedNamespace block where the privileged SA regex is evaluated
  3. Falls through to the openshift-ingress specific check which only looks at the ingress controller label
  4. NPs without that label are denied regardless of SA privileges

This PR adds the privileged SA check before the ingress controller label check in the openshift-ingress block, so that trusted operators can manage NetworkPolicies for their own pods without requiring the ingress controller label.

Jira: ROSAENG-60641

Context

RHOAI deploys pods into openshift-ingress as part of its gateway architecture. With the OCP 4.22 deny-all in place, the operator needs to create NetworkPolicies for those pods. On ROSA, the webhook blocks the operator SA (system:serviceaccount:redhat-ods-operator:*) from doing so, even though it matches the privileged SA regex (redhat-*). This makes RHOAI non-functional on ROSA + OCP 4.22.

Validation

  • Added rhoaiServiceAccount() test helper simulating system:serviceaccount:redhat-ods-operator:redhat-ods-operator-controller-manager
  • Added test: privileged SA (redhat-*) can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: privileged SA (openshift-*) can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: unprivileged SA is still denied when creating NPs in openshift-ingress without the label
  • Existing tests unchanged and still pass

Summary by CodeRabbit

  • Bug Fixes
    • Requests from privileged service accounts in the openshift-ingress namespace are now allowed to manage network policies even when the usual ingress-related label is missing.
    • Added coverage to ensure privileged accounts are granted access while unprivileged accounts continue to be denied in the same scenario.

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

@ugiordan: GitHub didn't allow me to request PR reviews from the following users: michaelcourcy.

Note that only openshift members and repo collaborators can review this PR, and authors cannot review their own PRs.

Details

In response to this:

Summary

OCP 4.22 introduced a deny-all NetworkPolicy (openshift-ingress-deny-all) in the openshift-ingress namespace via NE-2501. This requires operators that deploy pods into openshift-ingress (such as RHOAI's kube-auth-proxy and payload-processing) to create explicit allow NetworkPolicies for their pods.

The current webhook logic has a special case for openshift-ingress that skips the privileged SA check entirely and only allows NPs whose podSelector contains ingresscontroller.operator.openshift.io/deployment-ingresscontroller with a non-default value. This blocks privileged service accounts (matching redhat-*, openshift-*, etc.) from creating NetworkPolicies for non-ingress-controller pods in that namespace.

The flow today:

  1. isAllowedNamespace("openshift-ingress") returns true (explicit carve-out on line 119)
  2. This skips the !isAllowedNamespace block where the privileged SA regex is evaluated
  3. Falls through to the openshift-ingress specific check which only looks at the ingress controller label
  4. NPs without that label are denied regardless of SA privileges

This PR adds the privileged SA check before the ingress controller label check in the openshift-ingress block, so that trusted operators can manage NetworkPolicies for their own pods without requiring the ingress controller label.

Context

Validation

  • Added rhoaiServiceAccount() test helper simulating system:serviceaccount:redhat-ods-operator:redhat-ods-operator-controller-manager
  • Added test: RHOAI SA can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: privileged SA (openshift-*) can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: unprivileged SA is still denied when creating NPs in openshift-ingress without the label
  • Existing tests unchanged and still pass

/cc @michaelcourcy

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.

@coderabbitai

coderabbitai Bot commented Jun 26, 2026

Copy link
Copy Markdown

Walkthrough

The webhook now allows privileged service accounts to manage NetworkPolicy objects in openshift-ingress before the ingress-controller label check. Tests add a RHOAI service-account identity and cover allowed and denied CRUD cases for that namespace.

Changes

Privileged NetworkPolicy allowance

Layer / File(s) Summary
Admission allowance path
pkg/webhooks/networkpolicies/networkpolicies.go
openshift-ingress requests from matching privileged service-account groups now return an allowed admission response and set the request UID.
CRUD coverage for service accounts
pkg/webhooks/networkpolicies/networkpolicies_test.go
A RHOAI service-account test identity is added, and CRUD cases cover privileged allow and unprivileged deny behavior for openshift-ingress NetworkPolicies.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
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 The added test titles are static literals; generated testIDs derive only from fixed verb names and fixed case names, with no runtime data or random values.
Test Structure And Quality ✅ Passed The new cases are table-driven unit tests with existing repo patterns, clear t.Fatalf messages, and no cluster setup/Eventually waits to manage.
Microshift Test Compatibility ✅ Passed The added tests are plain Go unit tests (testing.T), not Ginkgo e2e, and they use only NetworkPolicy/admission logic with no MicroShift-unsupported APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed Added tests are plain unit tests, not Ginkgo e2e tests, and they make no multi-node/SNO topology assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Only NetworkPolicy admission logic and tests changed; no deployments, replicas, affinity, node selectors, or topology-aware scheduling code were added.
Ote Binary Stdout Contract ✅ Passed The PR only changes webhook logic and unit tests; neither file adds stdout writes in main/init/TestMain/suite setup.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No new Ginkgo/e2e tests were added; the change is webhook logic plus unit tests only, with no IPv4 literals or external connectivity.
No-Weak-Crypto ✅ Passed Touched webhook code only adds namespace/group checks and tests; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons found.
Container-Privileges ✅ Passed PR only touches Go webhook/test logic; no container/K8s manifests or privilege settings (privileged, hostPID, hostNetwork, SYS_ADMIN, allowPrivilegeEscalation) were added.
No-Sensitive-Data-In-Logs ✅ Passed No new log statements were added; existing logs only emit operation and namespace, and tests use synthetic identities.
Title check ✅ Passed The title accurately summarizes the main change: privileged service accounts can create NetworkPolicies in openshift-ingress.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@michaelryanmcneill

Copy link
Copy Markdown

/assign @joshbranham

@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

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

@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 (1)
pkg/webhooks/networkpolicies/networkpolicies.go (1)

99-108: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: de-duplicate the privileged-SA group loop.

This loop is identical to the one at Lines 85-91 (only the message differs). Consider extracting a small helper (e.g. isPrivilegedServiceAccountGroup(request)) to keep the two paths in sync.

🤖 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/webhooks/networkpolicies/networkpolicies.go` around lines 99 - 108, The
privileged service account group check is duplicated in the NetworkPolicies
admission flow, which can drift between the two paths. Extract the shared loop
into a small helper such as isPrivilegedServiceAccountGroup(request) or similar
in networkpolicies.go, and reuse it from both call sites so the matching logic
stays identical while only the Allowed message text remains different.
🤖 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 `@pkg/webhooks/networkpolicies/networkpolicies.go`:
- Around line 99-108: The privileged service account early return in the network
policy admission flow bypasses the default-ingress protection check, so update
the logic in the NetworkPolicies webhook to keep the ingressName == "default"
guard applying even for matched privileged groups. Adjust the matching in the
request.UserInfo.Groups loop so the allow path only grants access when the
target policy is not the default ingress, and tighten
privilegedServiceAccountGroupsRe if exact group matching is intended by
anchoring the pattern or comparing the full group string directly. Keep the
behavior centered around the existing admission decision in the webhook handler.

---

Nitpick comments:
In `@pkg/webhooks/networkpolicies/networkpolicies.go`:
- Around line 99-108: The privileged service account group check is duplicated
in the NetworkPolicies admission flow, which can drift between the two paths.
Extract the shared loop into a small helper such as
isPrivilegedServiceAccountGroup(request) or similar in networkpolicies.go, and
reuse it from both call sites so the matching logic stays identical while only
the Allowed message text remains different.
🪄 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: b16a835e-611b-4905-81c9-286737aaa194

📥 Commits

Reviewing files that changed from the base of the PR and between d07c765 and b89dd2b.

📒 Files selected for processing (2)
  • pkg/webhooks/networkpolicies/networkpolicies.go
  • pkg/webhooks/networkpolicies/networkpolicies_test.go

Comment thread pkg/webhooks/networkpolicies/networkpolicies.go
@joshbranham

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jun 26, 2026
@openshift-ci

openshift-ci Bot commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: joshbranham, ugiordan

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

The pull request process is described 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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jun 26, 2026
@joshbranham

Copy link
Copy Markdown
Contributor

/retest

…in openshift-ingress

The openshift-ingress namespace has a special-case check that only
allows NetworkPolicies whose podSelector targets a non-default ingress
controller. This blocks privileged service accounts (matching
redhat-*, openshift-*, etc.) from creating NetworkPolicies for
non-ingress-controller pods deployed in that namespace.

OCP 4.22 introduced a deny-all NetworkPolicy in openshift-ingress,
making it necessary for operators like RHOAI to create explicit allow
policies for their pods (kube-auth-proxy, payload-processing). Without
this fix, the webhook blocks these policies even from privileged SAs.

Add the privileged SA check before the ingress controller label check
so that trusted operators can manage NetworkPolicies in
openshift-ingress without requiring the ingress controller label.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@joshbranham

Copy link
Copy Markdown
Contributor

This will need to be rebased

@ugiordan ugiordan force-pushed the fix/networkpolicies-privileged-sa-openshift-ingress branch from b89dd2b to 12cb46e Compare June 29, 2026 16:13
@ugiordan

Copy link
Copy Markdown
Contributor Author

This will need to be rebased

done

@joshbranham

Copy link
Copy Markdown
Contributor

/test ci/prow/pr-check

@joshbranham

Copy link
Copy Markdown
Contributor

/retest

@joshbranham joshbranham changed the title Allow privileged service accounts to create NetworkPolicies in openshift-ingress ROSAENG-60641: Allow privileged service accounts to create NetworkPolicies in openshift-ingress Jun 29, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jun 29, 2026
@openshift-ci-robot

openshift-ci-robot commented Jun 29, 2026

Copy link
Copy Markdown

@ugiordan: This pull request references ROSAENG-60641 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 bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

OCP 4.22 introduced a deny-all NetworkPolicy (openshift-ingress-deny-all) in the openshift-ingress namespace via NE-2501. This requires operators that deploy pods into openshift-ingress to create explicit allow NetworkPolicies for their pods.

The current webhook logic has a special case for openshift-ingress that skips the privileged SA check entirely and only allows NPs whose podSelector contains ingresscontroller.operator.openshift.io/deployment-ingresscontroller with a non-default value. This blocks privileged service accounts (matching redhat-*, openshift-*, etc.) from creating NetworkPolicies for non-ingress-controller pods in that namespace.

The flow today:

  1. isAllowedNamespace("openshift-ingress") returns true (explicit carve-out on line 119)
  2. This skips the !isAllowedNamespace block where the privileged SA regex is evaluated
  3. Falls through to the openshift-ingress specific check which only looks at the ingress controller label
  4. NPs without that label are denied regardless of SA privileges

This PR adds the privileged SA check before the ingress controller label check in the openshift-ingress block, so that trusted operators can manage NetworkPolicies for their own pods without requiring the ingress controller label.

Jira: ROSAENG-60641

Context

RHOAI deploys pods into openshift-ingress as part of its gateway architecture. With the OCP 4.22 deny-all in place, the operator needs to create NetworkPolicies for those pods. On ROSA, the webhook blocks the operator SA (system:serviceaccount:redhat-ods-operator:*) from doing so, even though it matches the privileged SA regex (redhat-*). This makes RHOAI non-functional on ROSA + OCP 4.22.

Validation

  • Added rhoaiServiceAccount() test helper simulating system:serviceaccount:redhat-ods-operator:redhat-ods-operator-controller-manager
  • Added test: privileged SA (redhat-*) can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: privileged SA (openshift-*) can CRUD NetworkPolicies in openshift-ingress without the ingress controller label
  • Added test: unprivileged SA is still denied when creating NPs in openshift-ingress without the label
  • Existing tests unchanged and still pass

Summary by CodeRabbit

  • Bug Fixes
  • Requests from privileged service accounts in the openshift-ingress namespace are now allowed to manage network policies even when the usual ingress-related label is missing.
  • Added coverage to ensure privileged accounts are granted access while unprivileged accounts continue to be denied in the same scenario.

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.

@joshbranham joshbranham merged commit be8800a into openshift:master Jun 29, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants