This is an automated email from the ASF dual-hosted git repository.
potiuk pushed a commit to branch chart/v1-2x-test
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/chart/v1-2x-test by this push:
new 6b92f1535e2 [chart/v1-2x-test] Apply Default Security Context to OTel
Collector Container (#74268) (#76896)
6b92f1535e2 is described below
commit 6b92f1535e2d8d72157bcc6a0a6e8750560081a8
Author: Deep <[email protected]>
AuthorDate: Thu Nov 12 19:51:52 2026 +0530
[chart/v1-2x-test] Apply Default Security Context to OTel Collector
Container (#74268) (#76896)
(cherry picked from commit 73fae2472c721e887e6eebb72a68408bcead024c)
Signed-off-by: Subhadeep Maity
<[email protected]>
Co-authored-by: Cursor <[email protected]>
---
chart/README.md | 1 +
.../otel-collector/otel-collector-deployment.yaml | 5 ++++-
chart/values.schema.json | 2 +-
chart/values.yaml | 2 ++
.../otel_collector/test_otel_collector.py | 21 +++++++++++++++++++++
.../helm_tests/security/test_security_context.py | 16 ++++++++++++----
6 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/chart/README.md b/chart/README.md
index 248e0b7a15f..7b39fdd6a7c 100644
--- a/chart/README.md
+++ b/chart/README.md
@@ -52,6 +52,7 @@ cluster using the [Helm](https://helm.sh) package manager.
* Container-specific Service Account Token Volume configuration
implementing Principle of Least Privilege
* Only scheduler containers receive API access; init and sidecar containers
operate without tokens
* Defense-in-depth security with both ServiceAccount and Pod-level controls
+ * Default container hardening with security contexts set
* Compatibility with security policies like Kyverno and compliance
frameworks
* Monitoring:
* StatsD/Prometheus metrics for Airflow
diff --git a/chart/templates/otel-collector/otel-collector-deployment.yaml
b/chart/templates/otel-collector/otel-collector-deployment.yaml
index 0bea8a53109..a5ad072efbc 100644
--- a/chart/templates/otel-collector/otel-collector-deployment.yaml
+++ b/chart/templates/otel-collector/otel-collector-deployment.yaml
@@ -26,6 +26,7 @@
{{- $tolerations := or .Values.otelCollector.tolerations .Values.tolerations }}
{{- $topologySpreadConstraints := or
.Values.otelCollector.topologySpreadConstraints
.Values.topologySpreadConstraints }}
{{- $revisionHistoryLimit := include "airflow.revisionHistoryLimit" (list
.Values.otelCollector.revisionHistoryLimit .Values.revisionHistoryLimit) }}
+{{- $containerSecurityContext := include "externalContainerSecurityContext"
(list .Values.otelCollector .Values) }}
apiVersion: apps/v1
kind: Deployment
metadata:
@@ -83,7 +84,9 @@ spec:
- name: otel-collector
image: {{ template "otel_collector_image" . }}
imagePullPolicy: {{ .Values.images.otelCollector.pullPolicy }}
- securityContext: {{- toYaml
.Values.otelCollector.securityContexts.container | nindent 12 }}
+ {{- if $containerSecurityContext }}
+ securityContext: {{ $containerSecurityContext | nindent 12 }}
+ {{- end }}
args: {{- tpl (toYaml .Values.otelCollector.args) . | nindent 12 }}
ports:
- name: otlp-grpc
diff --git a/chart/values.schema.json b/chart/values.schema.json
index b0baac49808..d850333b1be 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -9896,7 +9896,7 @@
"x-docsSection": "Kubernetes"
},
"container": {
- "description": "Container security context
definition for the OTel Collector.",
+ "description": "Container security context
definition for the OTel Collector. By default, privilege escalation is disabled
and all capabilities are dropped unless `securityContexts.disableDefaults` is
enabled.",
"type": "object",
"$ref":
"#/definitions/io.k8s.api.core.v1.SecurityContext",
"default": {},
diff --git a/chart/values.yaml b/chart/values.yaml
index 6e0cc035d0b..f1bbcd33b55 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -3767,6 +3767,8 @@ otelCollector:
labels: {}
podAnnotations: {}
+ # Detailed security contexts for the OTel Collector.
+ # By default, the container disallows privilege escalation and drops all
capabilities.
securityContexts:
pod: {}
container: {}
diff --git a/helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py
b/helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py
index b7d84347fb9..73698d6b54e 100644
--- a/helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py
+++ b/helm-tests/tests/helm_tests/otel_collector/test_otel_collector.py
@@ -159,6 +159,27 @@ class TestOtelCollectorDeployment:
"--config=/etc/otel-collector/config.yml"
]
+ def test_default_container_security_context(self):
+ docs = render_chart(
+ values={"otelCollector": {"tracesEnabled": True}},
show_only=[DEPLOYMENT_TEMPLATE]
+ )
+
+ assert
jmespath.search("spec.template.spec.containers[0].securityContext", docs[0]) ==
{
+ "allowPrivilegeEscalation": False,
+ "capabilities": {"drop": ["ALL"]},
+ }
+
+ def test_container_security_context_disable_defaults(self):
+ docs = render_chart(
+ values={
+ "securityContexts": {"disableDefaults": True},
+ "otelCollector": {"tracesEnabled": True},
+ },
+ show_only=[DEPLOYMENT_TEMPLATE],
+ )
+
+ assert
jmespath.search("spec.template.spec.containers[0].securityContext", docs[0]) is
None
+
def test_args_override(self):
custom = ["--config=/etc/otel-collector/config.yml",
"--feature-gates=+foo"]
docs = render_chart(
diff --git a/helm-tests/tests/helm_tests/security/test_security_context.py
b/helm-tests/tests/helm_tests/security/test_security_context.py
index b8fc29cb0dd..8574c7a70d5 100644
--- a/helm-tests/tests/helm_tests/security/test_security_context.py
+++ b/helm-tests/tests/helm_tests/security/test_security_context.py
@@ -383,6 +383,7 @@ class TestSecurityContext:
"executor": "CeleryExecutor,KubernetesExecutor",
"cleanup": {"enabled": True},
"flower": {"enabled": True},
+ "otelCollector": {"tracesEnabled": True},
"pgbouncer": {"enabled": True},
},
show_only=[
@@ -394,6 +395,7 @@ class TestSecurityContext:
"templates/jobs/create-user-job.yaml",
"templates/jobs/migrate-database-job.yaml",
"templates/triggerer/triggerer-deployment.yaml",
+ "templates/otel-collector/otel-collector-deployment.yaml",
"templates/pgbouncer/pgbouncer-deployment.yaml",
"templates/statsd/statsd-deployment.yaml",
"templates/redis/redis-statefulset.yaml",
@@ -407,18 +409,19 @@ class TestSecurityContext:
"spec.jobTemplate.spec.template.spec.securityContext", docs[0]
)
- for doc in docs[1:-3]:
+ for doc in docs[1:-4]:
assert ctx_value_container == jmespath.search(
"spec.template.spec.containers[0].securityContext", doc
)
assert ctx_value_pod ==
jmespath.search("spec.template.spec.securityContext", doc)
- # Global security context is not propagated to pgbouncer, redis and
statsd, so we test default value
+ # Global security context is not propagated to otel collector,
pgbouncer, redis and statsd,
+ # so we test default value
default_ctx_value_container = {"allowPrivilegeEscalation": False,
"capabilities": {"drop": ["ALL"]}}
default_ctx_value_pod_pgbouncer = {"runAsUser": 65534}
default_ctx_value_pod_statsd = {"runAsUser": 65534}
default_ctx_value_pod_redis = {"runAsUser": 0}
- for doc in docs[-3:]:
+ for doc in docs[-4:]:
assert default_ctx_value_container == jmespath.search(
"spec.template.spec.containers[0].securityContext", doc
)
@@ -523,6 +526,7 @@ class TestSecurityContext:
"apiServer": security_context,
"workers": workers_values,
"flower": {"enabled": True, **security_context},
+ "otelCollector": {"tracesEnabled": True, **security_context},
"statsd": security_context,
"createUserJob": security_context,
"migrateDatabaseJob": security_context,
@@ -537,6 +541,7 @@ class TestSecurityContext:
"templates/api-server/api-server-deployment.yaml",
"templates/dag-processor/dag-processor-deployment.yaml",
"templates/workers/worker-deployment.yaml",
+ "templates/otel-collector/otel-collector-deployment.yaml",
"templates/statsd/statsd-deployment.yaml",
"templates/jobs/create-user-job.yaml",
"templates/jobs/migrate-database-job.yaml",
@@ -1108,6 +1113,7 @@ class TestSecurityContext:
values={
"securityContexts": {"disableDefaults": True},
"flower": {"enabled": True},
+ "otelCollector": {"tracesEnabled": True},
"pgbouncer": {"enabled": True},
"statsd": {"enabled": True},
},
@@ -1123,10 +1129,12 @@ class TestSecurityContext:
"templates/pgbouncer/pgbouncer-deployment.yaml",
"templates/statsd/statsd-deployment.yaml",
"templates/redis/redis-statefulset.yaml",
+ "templates/otel-collector/otel-collector-deployment.yaml",
],
)
- assert all(v is None for v in
jmespath.search("[].spec.template.spec.securityContext", docs))
+ assert all(v is None for v in
jmespath.search("[].spec.template.spec.securityContext", docs[:-1]))
+ assert jmespath.search("spec.template.spec.securityContext", docs[-1])
== {}
assert all(
v is None for v in
jmespath.search("[].spec.template.spec.containers[0].securityContext", docs)
)