Skip to content
Closed
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
6 changes: 6 additions & 0 deletions charts/sourcegraph-executor/k8s/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ In addition to the documented values, the `executor` and `private-docker-registr
| Key | Type | Default | Description |
|-----|------|---------|-------------|
| executor.affinity | object | `{}` | Affinity, learn more from the [Kubernetes documentation](https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/#affinity-and-anti-affinity) |
| 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. |
| executor.ciliumNetworkPolicy.deniedFrontendServiceNames | list | `["sourcegraph-frontend-internal"]` | Sourcegraph services that are backed by frontend pods but should still be denied to executors. |
| executor.ciliumNetworkPolicy.enabled | bool | `false` | Create CiliumNetworkPolicy rules that allow executor controller and job pods to reach the user-facing frontend service and deny other Sourcegraph pods and services. This does not replace existing DNS, code host, or package registry allow policies. |
| executor.ciliumNetworkPolicy.frontendPodAppLabelValue | string | `"sourcegraph-frontend"` | Value of the `app` label on Sourcegraph frontend pods. |
| executor.ciliumNetworkPolicy.frontendServiceName | string | `"sourcegraph-frontend"` | Kubernetes Service name for the user-facing Sourcegraph frontend service that executor pods must be able to reach. |
| executor.ciliumNetworkPolicy.sourcegraphNamespace | string | `""` | Namespace where the Sourcegraph frontend and the rest of the Sourcegraph Helm chart run. Defaults to the Helm release namespace. |
| executor.configureRbac | bool | `true` | Whether to configure the necessary RBAC resources. Required only once for all executor deployments. |
| 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) |
| 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. |
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
{{- define "executor.ciliumNetworkPolicy.egressDeny" -}}
{{- $policy := .policy -}}
{{- $sourcegraphNamespace := .sourcegraphNamespace -}}
- toEndpoints:
- matchExpressions:
- key: io.kubernetes.pod.namespace
operator: In
values:
- {{ $sourcegraphNamespace | quote }}
- key: deploy
operator: In
values:
- sourcegraph
- key: app
operator: NotIn
values:
- {{ $policy.frontendPodAppLabelValue | quote }}
{{- range $serviceName := $policy.deniedFrontendServiceNames }}
- toServices:
- k8sService:
namespace: {{ $sourcegraphNamespace | quote }}
serviceName: {{ $serviceName | quote }}
{{- end }}
{{- if $policy.deniedFrontendPorts }}
- toEndpoints:
- matchLabels:
io.kubernetes.pod.namespace: {{ $sourcegraphNamespace | quote }}
app: {{ $policy.frontendPodAppLabelValue | quote }}
toPorts:
- ports:
{{- range $port := $policy.deniedFrontendPorts }}
- port: {{ $port | quote }}
protocol: TCP
{{- end }}
{{- end }}
{{- end }}

{{- define "executor.ciliumNetworkPolicy.egressAllow" -}}
{{- $policy := .policy -}}
{{- $sourcegraphNamespace := .sourcegraphNamespace -}}
- toServices:
- k8sService:
namespace: {{ $sourcegraphNamespace | quote }}
serviceName: {{ $policy.frontendServiceName | quote }}
{{- end }}

{{- if .Values.executor.ciliumNetworkPolicy.enabled }}
{{- $policy := .Values.executor.ciliumNetworkPolicy }}
{{- $sourcegraphNamespace := default .Release.Namespace $policy.sourcegraphNamespace }}
{{- $jobNamespace := default .Release.Namespace .Values.executor.namespace }}
{{- $egressDenyContext := dict "policy" $policy "sourcegraphNamespace" $sourcegraphNamespace }}
{{- $egressAllowContext := dict "policy" $policy "sourcegraphNamespace" $sourcegraphNamespace }}
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: {{ printf "%s-controller-egress-deny" (include "executor.name" .) | trunc 63 | trimSuffix "-" }}
namespace: {{ .Release.Namespace | quote }}
spec:
description: >-
Deny Sourcegraph executor controller pods from reaching Sourcegraph pods and
services other than the user-facing frontend service.
enableDefaultDeny:
egress: false
endpointSelector:
matchLabels:
app: {{ include "executor.name" . | quote }}
egress:
{{ include "executor.ciliumNetworkPolicy.egressAllow" $egressAllowContext | indent 4 }}
egressDeny:
{{ include "executor.ciliumNetworkPolicy.egressDeny" $egressDenyContext | indent 4 }}
---
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: {{ printf "%s-jobs-egress-deny" (include "executor.name" .) | trunc 63 | trimSuffix "-" }}
namespace: {{ $jobNamespace | quote }}
spec:
description: >-
Deny Sourcegraph executor job pods from reaching Sourcegraph pods and
services other than the user-facing frontend service.
enableDefaultDeny:
egress: false
endpointSelector:
matchExpressions:
- key: sourcegraph/job-id
operator: Exists
- key: sourcegraph/run-id
operator: Exists
egress:
{{ include "executor.ciliumNetworkPolicy.egressAllow" $egressAllowContext | indent 4 }}
egressDeny:
{{ include "executor.ciliumNetworkPolicy.egressDeny" $egressDenyContext | indent 4 }}
{{- end }}
84 changes: 84 additions & 0 deletions charts/sourcegraph-executor/k8s/tests/executor_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ templates:
- executor.Service.yaml
- executor.ConfigMap.yaml
- executor.PersistentVolumeClaim.yaml
- executor.CiliumNetworkPolicy.yaml
tests:
- it: should render the Deployment, Service, ConfigMap, PVC if executor is enabled
set:
Expand Down Expand Up @@ -131,3 +132,86 @@ tests:
path: spec.template.spec.securityContext.runAsUser
- isNull:
path: spec.template.spec.securityContext.runAsGroup

- it: should render CiliumNetworkPolicy deny guards when enabled
template: executor.CiliumNetworkPolicy.yaml
set:
executor:
queueNames:
- batches
- codeintel
namespace: executor-jobs
ciliumNetworkPolicy:
enabled: true
sourcegraphNamespace: sourcegraph
asserts:
- hasDocuments:
count: 2
- equal:
path: apiVersion
value: cilium.io/v2
documentIndex: 0
- equal:
path: kind
value: CiliumNetworkPolicy
documentIndex: 0
- equal:
path: metadata.name
value: executor-batches-codeintel-controller-egress-deny
documentIndex: 0
- equal:
path: metadata.namespace
value: NAMESPACE
documentIndex: 0
- equal:
path: spec.enableDefaultDeny.egress
value: false
documentIndex: 0
- equal:
path: spec.endpointSelector.matchLabels.app
value: executor-batches-codeintel
documentIndex: 0
- equal:
path: spec.egress[0].toServices[0].k8sService
value:
namespace: sourcegraph
serviceName: sourcegraph-frontend
documentIndex: 0
- equal:
path: apiVersion
value: cilium.io/v2
documentIndex: 1
- equal:
path: kind
value: CiliumNetworkPolicy
documentIndex: 1
- equal:
path: metadata.name
value: executor-batches-codeintel-jobs-egress-deny
documentIndex: 1
- equal:
path: metadata.namespace
value: executor-jobs
documentIndex: 1
- equal:
path: spec.endpointSelector.matchExpressions
value:
- key: sourcegraph/job-id
operator: Exists
- key: sourcegraph/run-id
operator: Exists
documentIndex: 1
- equal:
path: spec.egress[0].toServices[0].k8sService
value:
namespace: sourcegraph
serviceName: sourcegraph-frontend
documentIndex: 1
- equal:
path: spec.egressDeny[0].toEndpoints[0].matchExpressions[0]
value:
key: io.kubernetes.pod.namespace
operator: In
values:
- sourcegraph
documentIndex: 1
17 changes: 17 additions & 0 deletions charts/sourcegraph-executor/k8s/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,23 @@ executor:
storageSize: 10Gi
# -- The namespace in which jobs are generated by the executor.
namespace: "default"
ciliumNetworkPolicy:
# -- Create CiliumNetworkPolicy rules that allow executor controller and job pods to reach the user-facing frontend service and deny other Sourcegraph pods and services. This does not replace existing DNS, code host, or package registry allow policies.
enabled: false
# -- Namespace where the Sourcegraph frontend and the rest of the Sourcegraph Helm chart run. Defaults to the Helm release namespace.
sourcegraphNamespace: ""
# -- Kubernetes Service name for the user-facing Sourcegraph frontend service that executor pods must be able to reach.
frontendServiceName: sourcegraph-frontend
# -- Value of the `app` label on Sourcegraph frontend pods.
frontendPodAppLabelValue: sourcegraph-frontend
# -- Sourcegraph services that are backed by frontend pods but should still be denied to executors.
deniedFrontendServiceNames:
- sourcegraph-frontend-internal
# -- Frontend pod ports to deny directly, even though the frontend pod is otherwise excluded from the broad Sourcegraph pod deny rule.
deniedFrontendPorts:
- "6060"
- "3090"
- "80"
# -- The path to the kubeconfig file. If not specified, the in-cluster config is used.
kubeconfigPath: ""
# -- DEPRECATED: Use `executor.containerSecurityContext` or `executor.podSecurityContext` instead.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# Sourcegraph Executor network policies for native Kubernetes
#
# Description:
#
# - Executors must not be allowed to connect to any Sourcegraph-internal services,
# except the sourcegraph-frontend service
#
# - Many Kubernetes platforms do not block inter-namespace communication by default
#
# - Unless your instance requires external pods to be able to connect to
# Sourcegraph-internal services, ex. external Prometheus scraping pod metrics,
# then Sourcegraph-internal services should not be reachable outside of
# the instance's namespace
#
# Native Kubernetes NetworkPolicy supports allow rules only, like:
#
# - Block all ingress by default
# - Allow ingress by specified exceptions
#
# Usage:
#
# - Deploy both network policies in your Sourcegraph instance's namespace
#
# - You can still use `frontendUrl: http://sourcegraph-frontend:30080`
# in your override file for the sourcegraph-executor Helm charts,
# to avoid paying egress / ingress charges for the Executors' traffic
#
# Effect:
#
# - Executor pods can reach the frontend HTTP service
# - Executor pods cannot reach frontend internal/debug ports
# - Executor pods cannot reach other Sourcegraph pods or services
# - Executor egress to DNS, kube API, code hosts, package registries, and other
# external services is unchanged
#
# Notes:
#
# - Kubernetes NetworkPolicy rules are additive; if another policy already allows
# executor ingress to backend pods, remove or narrow that broader allow policy
#
# - This policy relies on all Sourcegraph + executor pods having at least
# the default labels from their respective Helm charts
#
# - To protect additional pods (ex. src-serve-git), either:
# - Apply the deploy=sourcegraph label to them
# - Or add an identifying label for them in the spec.podSelector.matchExpressions
# of the sourcegraph-internal-pods-block-executors policy
#
# - If you need pods from outside of your Sourcegraph instance's namespace
# to continue to be able to connect to backend pods, then uncomment the
# `namespaceSelector: {}` line

---

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sourcegraph-pods-block-executors
spec:
podSelector:
matchExpressions:
- key: deploy
operator: In
values:
- sourcegraph
- key: app.kubernetes.io/component
operator: NotIn
values:
- executor
- key: sourcegraph/job-id
operator: DoesNotExist
- key: sourcegraph/run-id
operator: DoesNotExist
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchExpressions:
- key: app.kubernetes.io/component
operator: NotIn
values:
- executor
- key: sourcegraph/job-id
operator: DoesNotExist
- key: sourcegraph/run-id
operator: DoesNotExist
# namespaceSelector: {}

---

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: sourcegraph-frontend-allow-http-from-anywhere
spec:
podSelector:
matchLabels:
deploy: sourcegraph
app: sourcegraph-frontend
policyTypes:
- Ingress
ingress:
- ports:
- protocol: TCP
port: http
Loading