Skip to content

Commit 14145bd

Browse files
Add executor Cilium network policy guard
Amp-Thread-ID: https://ampcode.com/threads/T-019e7da4-9296-7370-a039-57f2e8351c24 Co-authored-by: Amp <amp@ampcode.com>
1 parent 0eb4889 commit 14145bd

4 files changed

Lines changed: 172 additions & 0 deletions

File tree

charts/sourcegraph-executor/k8s/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ In addition to the documented values, the `executor` and `private-docker-registr
5353
| Key | Type | Default | Description |
5454
|-----|------|---------|-------------|
5555
| executor.affinity | object | `{}` | Affinity, learn more from the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) |
56+
| executor.ciliumNetworkPolicy.deniedFrontendPorts | list | `["6060","3090","80"]` | Frontend pod ports to deny directly, even though the frontend pod is otherwise excluded from the broad Sourcegraph pod deny rule. |
57+
| executor.ciliumNetworkPolicy.deniedFrontendServiceNames | list | `["sourcegraph-frontend-internal"]` | Sourcegraph services that are backed by frontend pods but should still be denied to executors. |
58+
| executor.ciliumNetworkPolicy.enabled | bool | `false` | Create CiliumNetworkPolicy deny rules that prevent executor controller and job pods from reaching Sourcegraph pods and services other than the user-facing frontend service. This is a deny-only guard: it does not replace existing DNS, code host, package registry, or frontend allow policies. |
59+
| executor.ciliumNetworkPolicy.frontendPodAppLabelValue | string | `"sourcegraph-frontend"` | Value of the `app` label on Sourcegraph frontend pods. |
60+
| executor.ciliumNetworkPolicy.sourcegraphNamespace | string | `""` | Namespace where the Sourcegraph frontend and the rest of the Sourcegraph Helm chart run. Defaults to the Helm release namespace. |
5661
| executor.configureRbac | bool | `true` | Whether to configure the necessary RBAC resources. Required only once for all executor deployments. |
5762
| executor.containerSecurityContext | object | `{"privileged":false}` | Security context for the container, learn more from the [Kubernetes documentation](https://kubernetes.io/docs/tasks/configure-pod-container/security-context/#set-the-security-context-for-a-container) |
5863
| executor.debug.keepJobs | string | `"false"` | If true, Kubernetes jobs will not be deleted after they complete. Not recommended for production use as it can hit cluster limits. |
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
{{- define "executor.ciliumNetworkPolicy.egressDeny" -}}
2+
{{- $policy := .policy -}}
3+
{{- $sourcegraphNamespace := .sourcegraphNamespace -}}
4+
- toEndpoints:
5+
- matchExpressions:
6+
- key: io.kubernetes.pod.namespace
7+
operator: In
8+
values:
9+
- {{ $sourcegraphNamespace | quote }}
10+
- key: deploy
11+
operator: In
12+
values:
13+
- sourcegraph
14+
- key: app
15+
operator: NotIn
16+
values:
17+
- {{ $policy.frontendPodAppLabelValue | quote }}
18+
{{- range $serviceName := $policy.deniedFrontendServiceNames }}
19+
- toServices:
20+
- k8sService:
21+
namespace: {{ $sourcegraphNamespace | quote }}
22+
serviceName: {{ $serviceName | quote }}
23+
{{- end }}
24+
{{- if $policy.deniedFrontendPorts }}
25+
- toEndpoints:
26+
- matchLabels:
27+
io.kubernetes.pod.namespace: {{ $sourcegraphNamespace | quote }}
28+
app: {{ $policy.frontendPodAppLabelValue | quote }}
29+
toPorts:
30+
- ports:
31+
{{- range $port := $policy.deniedFrontendPorts }}
32+
- port: {{ $port | quote }}
33+
protocol: TCP
34+
{{- end }}
35+
{{- end }}
36+
{{- end }}
37+
38+
{{- if .Values.executor.ciliumNetworkPolicy.enabled }}
39+
{{- $policy := .Values.executor.ciliumNetworkPolicy }}
40+
{{- $sourcegraphNamespace := default .Release.Namespace $policy.sourcegraphNamespace }}
41+
{{- $jobNamespace := default .Release.Namespace .Values.executor.namespace }}
42+
{{- $egressDenyContext := dict "policy" $policy "sourcegraphNamespace" $sourcegraphNamespace }}
43+
---
44+
apiVersion: cilium.io/v2
45+
kind: CiliumNetworkPolicy
46+
metadata:
47+
name: {{ printf "%s-controller-egress-deny" (include "executor.name" .) | trunc 63 | trimSuffix "-" }}
48+
namespace: {{ .Release.Namespace | quote }}
49+
spec:
50+
description: >-
51+
Deny Sourcegraph executor controller pods from reaching Sourcegraph pods and
52+
services other than the user-facing frontend service.
53+
enableDefaultDeny:
54+
egress: false
55+
endpointSelector:
56+
matchLabels:
57+
app: {{ include "executor.name" . | quote }}
58+
egressDeny:
59+
{{ include "executor.ciliumNetworkPolicy.egressDeny" $egressDenyContext | indent 4 }}
60+
---
61+
apiVersion: cilium.io/v2
62+
kind: CiliumNetworkPolicy
63+
metadata:
64+
name: {{ printf "%s-jobs-egress-deny" (include "executor.name" .) | trunc 63 | trimSuffix "-" }}
65+
namespace: {{ $jobNamespace | quote }}
66+
spec:
67+
description: >-
68+
Deny Sourcegraph executor job pods from reaching Sourcegraph pods and
69+
services other than the user-facing frontend service.
70+
enableDefaultDeny:
71+
egress: false
72+
endpointSelector:
73+
matchExpressions:
74+
- key: sourcegraph/job-id
75+
operator: Exists
76+
- key: sourcegraph/run-id
77+
operator: Exists
78+
egressDeny:
79+
{{ include "executor.ciliumNetworkPolicy.egressDeny" $egressDenyContext | indent 4 }}
80+
{{- end }}

charts/sourcegraph-executor/k8s/tests/executor_test.yaml

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ templates:
44
- executor.Service.yaml
55
- executor.ConfigMap.yaml
66
- executor.PersistentVolumeClaim.yaml
7+
- executor.CiliumNetworkPolicy.yaml
78
tests:
89
- it: should render the Deployment, Service, ConfigMap, PVC if executor is enabled
910
set:
@@ -131,3 +132,74 @@ tests:
131132
path: spec.template.spec.securityContext.runAsUser
132133
- isNull:
133134
path: spec.template.spec.securityContext.runAsGroup
135+
136+
- it: should render CiliumNetworkPolicy deny guards when enabled
137+
template: executor.CiliumNetworkPolicy.yaml
138+
set:
139+
executor:
140+
queueNames:
141+
- batches
142+
- codeintel
143+
namespace: executor-jobs
144+
ciliumNetworkPolicy:
145+
enabled: true
146+
sourcegraphNamespace: sourcegraph
147+
asserts:
148+
- hasDocuments:
149+
count: 2
150+
- equal:
151+
path: apiVersion
152+
value: cilium.io/v2
153+
documentIndex: 0
154+
- equal:
155+
path: kind
156+
value: CiliumNetworkPolicy
157+
documentIndex: 0
158+
- equal:
159+
path: metadata.name
160+
value: executor-batches-codeintel-controller-egress-deny
161+
documentIndex: 0
162+
- equal:
163+
path: metadata.namespace
164+
value: NAMESPACE
165+
documentIndex: 0
166+
- equal:
167+
path: spec.enableDefaultDeny.egress
168+
value: false
169+
documentIndex: 0
170+
- equal:
171+
path: spec.endpointSelector.matchLabels.app
172+
value: executor-batches-codeintel
173+
documentIndex: 0
174+
- equal:
175+
path: apiVersion
176+
value: cilium.io/v2
177+
documentIndex: 1
178+
- equal:
179+
path: kind
180+
value: CiliumNetworkPolicy
181+
documentIndex: 1
182+
- equal:
183+
path: metadata.name
184+
value: executor-batches-codeintel-jobs-egress-deny
185+
documentIndex: 1
186+
- equal:
187+
path: metadata.namespace
188+
value: executor-jobs
189+
documentIndex: 1
190+
- equal:
191+
path: spec.endpointSelector.matchExpressions
192+
value:
193+
- key: sourcegraph/job-id
194+
operator: Exists
195+
- key: sourcegraph/run-id
196+
operator: Exists
197+
documentIndex: 1
198+
- equal:
199+
path: spec.egressDeny[0].toEndpoints[0].matchExpressions[0]
200+
value:
201+
key: io.kubernetes.pod.namespace
202+
operator: In
203+
values:
204+
- sourcegraph
205+
documentIndex: 1

charts/sourcegraph-executor/k8s/values.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,21 @@ executor:
9999
storageSize: 10Gi
100100
# -- The namespace in which jobs are generated by the executor.
101101
namespace: "default"
102+
ciliumNetworkPolicy:
103+
# -- Create CiliumNetworkPolicy deny rules that prevent executor controller and job pods from reaching Sourcegraph pods and services other than the user-facing frontend service. This is a deny-only guard: it does not replace existing DNS, code host, package registry, or frontend allow policies.
104+
enabled: false
105+
# -- Namespace where the Sourcegraph frontend and the rest of the Sourcegraph Helm chart run. Defaults to the Helm release namespace.
106+
sourcegraphNamespace: ""
107+
# -- Value of the `app` label on Sourcegraph frontend pods.
108+
frontendPodAppLabelValue: sourcegraph-frontend
109+
# -- Sourcegraph services that are backed by frontend pods but should still be denied to executors.
110+
deniedFrontendServiceNames:
111+
- sourcegraph-frontend-internal
112+
# -- Frontend pod ports to deny directly, even though the frontend pod is otherwise excluded from the broad Sourcegraph pod deny rule.
113+
deniedFrontendPorts:
114+
- "6060"
115+
- "3090"
116+
- "80"
102117
# -- The path to the kubeconfig file. If not specified, the in-cluster config is used.
103118
kubeconfigPath: ""
104119
# -- DEPRECATED: Use `executor.containerSecurityContext` or `executor.podSecurityContext` instead.

0 commit comments

Comments
 (0)