This is an automated email from the ASF dual-hosted git repository.
Miretpl pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/airflow.git
The following commit(s) were added to refs/heads/main by this push:
new 73fae2472c7 Apply Default Security Context to OTel Collector Container
(#74268)
73fae2472c7 is described below
commit 73fae2472c721e887e6eebb72a68408bcead024c
Author: Deep <[email protected]>
AuthorDate: Tue Nov 10 03:31:00 2026 +0530
Apply Default Security Context to OTel Collector Container (#74268)
* security context changes
Signed-off-by: Subhadeep Maity <[email protected]>
* update readme & improvement scope
Signed-off-by: Subhadeep Maity
<[email protected]>
* Update chart/README.md
Co-authored-by: Przemysław Mirowski
<[email protected]>
* tests updated
Signed-off-by: Subhadeep Maity
<[email protected]>
* Remove redundant OTel Collector news fragment
Signed-off-by: Subhadeep Maity
<[email protected]>
Co-authored-by: Cursor <[email protected]>
---------
Signed-off-by: Subhadeep Maity <[email protected]>
Signed-off-by: Subhadeep Maity
<[email protected]>
Co-authored-by: Subhadeep Maity <[email protected]>
Co-authored-by: Przemysław Mirowski
<[email protected]>
Co-authored-by: Cursor <[email protected]>
---
chart/README.md | 1 +
.../otel-collector/otel-collector-deployment.yaml | 5 ++++-
.../otel_collector/test_otel_collector.py | 21 +++++++++++++++++++++
.../helm_tests/security/test_security_context.py | 16 ++++++++++++----
chart/values.schema.json | 2 +-
chart/values.yaml | 2 ++
6 files changed, 41 insertions(+), 6 deletions(-)
diff --git a/chart/README.md b/chart/README.md
index 36827cef49f..34b02d87c9f 100644
--- a/chart/README.md
+++ b/chart/README.md
@@ -51,6 +51,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 abbcbc8bd9b..f0a1f611d15 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/tests/helm_tests/otel_collector/test_otel_collector.py
b/chart/tests/helm_tests/otel_collector/test_otel_collector.py
index 66cb5c58ec8..4aac817b118 100644
--- a/chart/tests/helm_tests/otel_collector/test_otel_collector.py
+++ b/chart/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/chart/tests/helm_tests/security/test_security_context.py
b/chart/tests/helm_tests/security/test_security_context.py
index a6d28434742..8d0f6737627 100644
--- a/chart/tests/helm_tests/security/test_security_context.py
+++ b/chart/tests/helm_tests/security/test_security_context.py
@@ -166,6 +166,7 @@ class TestSecurityContext:
"executor": "CeleryExecutor,KubernetesExecutor",
"cleanup": {"enabled": True},
"flower": {"enabled": True},
+ "otelCollector": {"tracesEnabled": True},
"pgbouncer": {"enabled": True},
},
show_only=[
@@ -176,6 +177,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",
@@ -189,18 +191,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
)
@@ -227,6 +230,7 @@ class TestSecurityContext:
"apiServer": security_context,
"workers": {"celery": security_context},
"flower": {"enabled": True, **security_context},
+ "otelCollector": {"tracesEnabled": True, **security_context},
"statsd": security_context,
"createUserJob": security_context,
"migrateDatabaseJob": security_context,
@@ -241,6 +245,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",
@@ -408,6 +413,7 @@ class TestSecurityContext:
values={
"securityContexts": {"disableDefaults": True},
"flower": {"enabled": True},
+ "otelCollector": {"tracesEnabled": True},
"pgbouncer": {"enabled": True},
"statsd": {"enabled": True},
},
@@ -423,10 +429,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)
)
diff --git a/chart/values.schema.json b/chart/values.schema.json
index de50eaca82f..ab3ce8c0b3a 100644
--- a/chart/values.schema.json
+++ b/chart/values.schema.json
@@ -7462,7 +7462,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 ae296a5f034..7895d99894a 100644
--- a/chart/values.yaml
+++ b/chart/values.yaml
@@ -2727,6 +2727,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: {}