nailo2c opened a new pull request, #69613:
URL: https://github.com/apache/airflow/pull/69613
closes: #49276
## Summary
Clusters that enforce Pod Security Standards or admission policies (e.g.
OPA/Gatekeeper) reject pods whose containers lack a security context. The
injected `airflow-xcom-sidecar` had no way to set one, making
`KubernetesPodOperator` with `do_xcom_push=True` unusable in such clusters
(admission webhook returns 403, see issue).
This PR makes the sidecar security context configurable at the two levels
requested in the issue:
- **Kubernetes connection** field `xcom_sidecar_container_security_context`
(JSON)
cluster-wide default set by the Deployment Manager, symmetric with the
existing sidecar image/resources fields.
- **`KubernetesPodOperator` argument**
`xcom_sidecar_container_security_context`
per-task override by the Dag author. The operator value wins over the
connection value (checked with `is not None`, so an explicit `{}` also
overrides).
## Verification
Unit tests cover the sidecar injection, the hook getter, and the
operator/connection precedence (including the explicit-`{}` override case).
Also verified end-to-end on a KinD cluster (KubernetesExecutor): one task
relying on the connection default and one overriding it per-operator, both with
`do_xcom_push=True`:
```console
$ kubectl get pod xcom-secctx-conn-default-thjh4ijf -o
jsonpath='{.spec.containers[?(@.name=="airflow-xcom-sidecar")].securityContext}'
{"allowPrivilegeEscalation":false,"readOnlyRootFilesystem":true,"seccompProfile":{"type":"RuntimeDefault"}}
$ kubectl get pod xcom-secctx-op-override-1nw3ttn1 -o
jsonpath='{.spec.containers[?(@.name=="airflow-xcom-sidecar")].securityContext}'
{"allowPrivilegeEscalation":false,"readOnlyRootFilesystem":false,"seccompProfile":{"type":"RuntimeDefault"}}
```
Both pods reached `phase=Succeeded` and the XCom values were pushed,
confirming the sidecar flow is unaffected.
<img width="854" height="434" alt="af_49276"
src="https://github.com/user-attachments/assets/b4979048-eaf5-47c0-8d26-cd8f41716f46"
/>
<br>
<br>
Here is the Dag I tested:
```python
import datetime
from airflow.providers.cncf.kubernetes.operators.pod import
KubernetesPodOperator
from airflow.sdk import DAG
with DAG(
dag_id="example_xcom_sidecar_security_context_49276",
schedule=None,
start_date=datetime.datetime(2026, 1, 1),
catchup=False,
tags=["49276"],
):
# Sidecar security context must come from the kubernetes_default
connection.
KubernetesPodOperator(
task_id="xcom_from_connection_default",
name="xcom-secctx-conn-default",
namespace="airflow",
image="alpine:3.24.1",
cmds=["sh", "-c", 'echo \'{"source": "connection"}\' >
/airflow/xcom/return.json'],
in_cluster=True,
do_xcom_push=True,
on_finish_action="keep_pod",
)
# Operator-level value must override the connection default
(readOnlyRootFilesystem flipped).
KubernetesPodOperator(
task_id="xcom_with_operator_override",
name="xcom-secctx-op-override",
namespace="airflow",
image="alpine:3.24.1",
cmds=["sh", "-c", 'echo \'{"source": "operator"}\' >
/airflow/xcom/return.json'],
in_cluster=True,
do_xcom_push=True,
xcom_sidecar_container_security_context={
"allowPrivilegeEscalation": False,
"readOnlyRootFilesystem": False,
"seccompProfile": {"type": "RuntimeDefault"},
},
on_finish_action="keep_pod",
)
```
---
##### Was generative AI tooling used to co-author this PR?
- [X] Yes — Claude Code (Fable 5)
Generated-by: Claude Code (Fable 5) following [the
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]