Skip to content

Commit 8855b54

Browse files
jkhelilcursoragent
andcommitted
feat(operator): add NetworkPolicy for operator namespace
Ship fixed NetworkPolicies for the operator's own namespace (tekton-operator / openshift-operators) as static manifests alongside the Deployment/RBAC, scoping the main operator and CR admission webhook pods for ingress/egress. No CR watches the operator's own namespace, so these cannot be reconciled and ship statically instead. Each podSelector targets this operator's own pod labels only, never an empty/namespace-wide selector, so the bundle never affects other pods sharing openshift-operators. Related to SRVKP-12050. Signed-off-by: Jawed khelil <jkhelil@redhat.com> Assisted-by: Claude Sonnet 5 (via Cursor) Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent 6a356d3 commit 8855b54

5 files changed

Lines changed: 205 additions & 0 deletions

File tree

config/kubernetes/base/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ resources:
3434
- ../../webhooks/
3535
- operator_service.yaml
3636
- pipelinesascode.yaml
37+
- networkpolicy.yaml
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
# Copyright 2026 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# NetworkPolicy resources for the operator's own namespace (tekton-operator). Unlike the
16+
# NetworkPolicies documented in docs/NetworkPolicy.md (reconciled dynamically by the operator for
17+
# operand namespaces such as tekton-pipelines/tekton-triggers), no CR watches the operator's own
18+
# namespace, so these ship statically with the install manifests/bundle instead. podSelectors are
19+
# scoped to this operator's own pod labels only — never an empty/namespace-wide selector — so
20+
# installing this bundle never affects other pods/operators that might share the namespace.
21+
apiVersion: networking.k8s.io/v1
22+
kind: NetworkPolicy
23+
metadata:
24+
name: tekton-operator
25+
spec:
26+
podSelector:
27+
matchLabels:
28+
name: tekton-operator
29+
policyTypes:
30+
- Ingress
31+
- Egress
32+
ingress:
33+
- from:
34+
- namespaceSelector:
35+
matchLabels:
36+
kubernetes.io/metadata.name: monitoring
37+
ports:
38+
- protocol: TCP
39+
port: 9090
40+
egress:
41+
- to:
42+
- namespaceSelector:
43+
matchLabels:
44+
kubernetes.io/metadata.name: kube-system
45+
podSelector:
46+
matchLabels:
47+
k8s-app: kube-dns
48+
ports:
49+
- protocol: UDP
50+
port: 53
51+
- protocol: TCP
52+
port: 53
53+
- ports:
54+
- protocol: TCP
55+
port: 443
56+
---
57+
apiVersion: networking.k8s.io/v1
58+
kind: NetworkPolicy
59+
metadata:
60+
name: tekton-operator-webhook
61+
spec:
62+
podSelector:
63+
matchLabels:
64+
name: tekton-operator-webhook
65+
policyTypes:
66+
- Ingress
67+
- Egress
68+
ingress:
69+
# Admission webhook callbacks originate from the API server; source IPs vary by cluster
70+
# network plugin, so no ingress "from" restriction is applied here.
71+
- ports:
72+
- protocol: TCP
73+
port: 8443
74+
egress:
75+
- to:
76+
- namespaceSelector:
77+
matchLabels:
78+
kubernetes.io/metadata.name: kube-system
79+
podSelector:
80+
matchLabels:
81+
k8s-app: kube-dns
82+
ports:
83+
- protocol: UDP
84+
port: 53
85+
- protocol: TCP
86+
port: 53
87+
- ports:
88+
- protocol: TCP
89+
port: 443

config/openshift/base/kustomization.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ resources:
5656
- ../../webhooks
5757
- operator_service.yaml
5858
- operator_servicemonitor.yaml
59+
- networkpolicy.yaml
5960
apiVersion: kustomize.config.k8s.io/v1beta1
6061
kind: Kustomization
6162

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright 2026 The Tekton Authors
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
# NetworkPolicy resources for the operator's own namespace (openshift-operators). Unlike the
16+
# NetworkPolicies documented in docs/NetworkPolicy.md (reconciled dynamically by the operator for
17+
# operand namespaces such as openshift-pipelines), no CR watches the operator's own namespace, so
18+
# these ship statically with the install manifests/OLM bundle instead. podSelectors are scoped to
19+
# this operator's own pod labels only — never an empty/namespace-wide selector, per the OLM bundle
20+
# guidance — so installing this bundle never affects other operators that may share the namespace
21+
# (openshift-operators is typically shared across many cluster-scoped operators).
22+
apiVersion: networking.k8s.io/v1
23+
kind: NetworkPolicy
24+
metadata:
25+
name: openshift-pipelines-operator
26+
spec:
27+
podSelector:
28+
matchLabels:
29+
name: openshift-pipelines-operator
30+
policyTypes:
31+
- Ingress
32+
- Egress
33+
ingress:
34+
- from:
35+
- namespaceSelector:
36+
matchLabels:
37+
openshift.io/cluster-monitoring: "true"
38+
ports:
39+
- protocol: TCP
40+
port: 9090
41+
egress:
42+
- to:
43+
- namespaceSelector:
44+
matchLabels:
45+
kubernetes.io/metadata.name: openshift-dns
46+
podSelector:
47+
matchLabels:
48+
dns.operator.openshift.io/daemonset-dns: default
49+
ports:
50+
- protocol: UDP
51+
port: 5353
52+
- protocol: TCP
53+
port: 5353
54+
- ports:
55+
- protocol: TCP
56+
port: 6443
57+
---
58+
apiVersion: networking.k8s.io/v1
59+
kind: NetworkPolicy
60+
metadata:
61+
name: tekton-operator-webhook
62+
spec:
63+
podSelector:
64+
matchLabels:
65+
name: tekton-operator-webhook
66+
policyTypes:
67+
- Ingress
68+
- Egress
69+
ingress:
70+
# Admission webhook callbacks originate from the API server; source IPs vary by cluster
71+
# network plugin, so no ingress "from" restriction is applied here.
72+
- ports:
73+
- protocol: TCP
74+
port: 8443
75+
egress:
76+
- to:
77+
- namespaceSelector:
78+
matchLabels:
79+
kubernetes.io/metadata.name: openshift-dns
80+
podSelector:
81+
matchLabels:
82+
dns.operator.openshift.io/daemonset-dns: default
83+
ports:
84+
- protocol: UDP
85+
port: 5353
86+
- protocol: TCP
87+
port: 5353
88+
- ports:
89+
- protocol: TCP
90+
port: 6443

docs/NetworkPolicy.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,30 @@ to the operand namespace (e.g. `tekton-pipelines` or `openshift-pipelines`):
6363
| API server port | 443 | 6443 |
6464
| Prometheus namespace label | `kubernetes.io/metadata.name: monitoring` | `openshift.io/cluster-monitoring: "true"` |
6565

66+
## Operator's own namespace
67+
68+
The operator's own namespace (`tekton-operator` on Kubernetes, `openshift-operators`
69+
on OpenShift) ships two fixed NetworkPolicies as static manifests alongside the
70+
operator's Deployment/RBAC — in `config/kubernetes/base/networkpolicy.yaml` and
71+
`config/openshift/base/networkpolicy.yaml` respectively. These are **not**
72+
reconciled by a controller and are **not** configurable via `spec.networkPolicy`:
73+
no CR watches the operator's own namespace, so there is nothing to gate this on.
74+
They are also not a namespace-wide default-deny — each policy's `podSelector` is
75+
scoped to one of the operator's own pods (`name: tekton-operator` /
76+
`name: openshift-pipelines-operator` for the main controller, and
77+
`name: tekton-operator-webhook` for the CR admission webhook) so that installing
78+
the operator's bundle never affects unrelated pods that might share the namespace
79+
(`openshift-operators` in particular is commonly shared by many operators).
80+
81+
| Policy | Direction | Port | Source / Destination |
82+
|---|---|---|---|
83+
| `tekton-operator` / `openshift-pipelines-operator` | ingress | TCP/9090 | Prometheus namespace |
84+
| | egress | UDP+TCP/53 or 5353 | DNS resolver pods |
85+
| | egress | TCP/443 or 6443 | API server |
86+
| `tekton-operator-webhook` | ingress | TCP/8443 | Any (admission webhook) |
87+
| | egress | UDP+TCP/53 or 5353 | DNS resolver pods |
88+
| | egress | TCP/443 or 6443 | API server |
89+
6690
## Disabling
6791

6892
```yaml

0 commit comments

Comments
 (0)