Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions pkg/webhooks/networkpolicies/networkpolicies.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,16 @@ func (s *networkpoliciesruleWebhook) authorized(request admissionctl.Request) ad
}

if np.GetNamespace() == "openshift-ingress" {
// Allow privileged service accounts (e.g. redhat-*, openshift-*) to
// manage NetworkPolicies for non-ingress-controller pods deployed in
// this namespace, such as kube-auth-proxy or payload-processing.
for _, group := range request.UserInfo.Groups {
if privilegedServiceAccountGroupsRe.Match([]byte(group)) {
ret = admissionctl.Allowed(fmt.Sprintf("Privileged service accounts in group(s) '%s' can operate on NetworkPolicies in openshift-ingress", strings.Join(request.UserInfo.Groups, ", ")))
ret.UID = request.AdmissionRequest.UID
return ret
}
}
Comment thread
joshbranham marked this conversation as resolved.
ingressName, labelFound := np.Spec.PodSelector.MatchLabels["ingresscontroller.operator.openshift.io/deployment-ingresscontroller"]
if !labelFound || ingressName == "default" {
ret = admissionctl.Denied(fmt.Sprintf("User '%s' prevented from creating network policy that may impact default ingress, which is managed by Red Hat. This is in an effort to prevent harmful actions that may cause unintended consequences or affect the stability of the cluster. If you have any questions about this, please reach out to Red Hat support at https://access.redhat.com/support", request.UserInfo.Username))
Expand Down
24 changes: 24 additions & 0 deletions pkg/webhooks/networkpolicies/networkpolicies_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (t crudTest) redhatServiceAccount() crudTest {
return t
}

func (t crudTest) rhoaiServiceAccount() crudTest {
t.testData.username = "system:serviceaccount:redhat-ods-operator:redhat-ods-operator-controller-manager"
t.testData.userGroups = []string{"system:serviceaccounts:redhat-ods-operator", "system:authenticated", "system:authenticated:oauth"}
return t
}

func (t crudTest) namespace(namespace string) crudTest {
t.testData.targetNamespace = namespace
return t
Expand Down Expand Up @@ -245,5 +251,23 @@ func TestUsers(t *testing.T) {
podSelector("ingresscontroller.operator.openshift.io/deployment-ingresscontroller", "custom").
regularUser().shouldBeAllowed())

// Privileged service accounts (redhat-*, openshift-*) should be allowed
// to create NetworkPolicies in openshift-ingress without the ingress
// controller label. This is needed for operators like RHOAI that deploy
// pods (kube-auth-proxy, payload-processing) into openshift-ingress.
tests = append(tests, newCrudTest("rhoai-sa-openshift-ingress-no-ingress-label").
namespace("openshift-ingress").
podSelector("app", "kube-auth-proxy").
rhoaiServiceAccount().shouldBeAllowedCRUD()...)
tests = append(tests, newCrudTest("privileged-sa-openshift-ingress-no-ingress-label").
namespace("openshift-ingress").
podSelector("app", "payload-processing").
allowedServiceAccount().shouldBeAllowedCRUD()...)
// Unprivileged SAs should still be denied
tests = append(tests, newCrudTest("unprivileged-sa-openshift-ingress-no-ingress-label").
namespace("openshift-ingress").
podSelector("app", "some-pod").
unprivilegedServiceAccount().shouldBeDeniedCRUD()...)

runNetworkPolicyTests(t, tests)
}