Repository: feast-dev/feast

Issue:
Bytewax Materializer Security Context Capabilities
## Expected Behavior 

Running the Bytewax materializer in a scaled and secured Kubernetes cluster should work, successfully running the materializer job.

## Current Behavior

In a managed, secured cluster, setting the securityContext capabilities may not be permitted, as is enabled by default. This causes the materialization job/s to fail.

## Steps to reproduce

Run the Bytewax materializer in an environment where securityContext capabilities cannot be specified/overriden in jobs.

### Specifications

- Version: 0.30.2
- Platform: EKS
- Subsystem: Python, Bytewax, Snowflake, Dynamodb

## Possible Solution

Add an optional boolean configuration parameter to the Bytewax materialization engine to dictate whether or not the (current default) security context options are included in the job spec. If set to `False` set the securityContext capabilities to `None`.


Discussion:

Resolving patch:
diff --git a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py
--- a/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py
+++ b/sdk/python/feast/infra/materialization/contrib/bytewax/bytewax_materialization_engine.py
@@ -58,6 +58,9 @@ class BytewaxMaterializationEngineConfig(FeastConfigBaseModel):
     annotations: dict = {}
     """ (optional) Annotations to apply to the job container. Useful for linking the service account to IAM roles, operational metadata, etc  """
 
+    include_security_context_capabilities: bool = True
+    """ (optional)  Include security context capabilities in the init and job container spec """
+
 
 class BytewaxMaterializationEngine(BatchMaterializationEngine):
     def __init__(
@@ -198,6 +201,9 @@ def _create_configuration_map(self, job_id, paths, feature_view, namespace):
             "apiVersion": "v1",
             "metadata": {
                 "name": f"feast-{job_id}",
+                "labels": {
+                    "feast-bytewax-materializer": "configmap",
+                },
             },
             "data": {
                 "feature_store.yaml": feature_store_configuration,
@@ -247,12 +253,22 @@ def _create_job_definition(self, job_id, namespace, pods, env):
         # Add any Feast configured environment variables
         job_env.extend(env)
 
+        securityContextCapabilities = None
+        if self.batch_engine_config.include_security_context_capabilities:
+            securityContextCapabilities = {
+                "add": ["NET_BIND_SERVICE"],
+                "drop": ["ALL"],
+            }
+
         job_definition = {
             "apiVersion": "batch/v1",
             "kind": "Job",
             "metadata": {
                 "name": f"dataflow-{job_id}",
                 "namespace": namespace,
+                "labels": {
+                    "feast-bytewax-materializer": "job",
+                },
             },
             "spec": {
                 "ttlSecondsAfterFinished": 3600,
@@ -262,6 +278,9 @@ def _create_job_definition(self, job_id, namespace, pods, env):
                 "template": {
                     "metadata": {
                         "annotations": self.batch_engine_config.annotations,
+                        "labels": {
+                            "feast-bytewax-materializer": "pod",
+                        },
                     },
                     "spec": {
                         "restartPolicy": "Never",
@@ -282,10 +301,7 @@ def _create_job_definition(self, job_id, namespace, pods, env):
                                 "resources": {},
                                 "securityContext": {
                                     "allowPrivilegeEscalation": False,
-                                    "capabilities": {
-                                        "add": ["NET_BIND_SERVICE"],
-                                        "drop": ["ALL"],
-                                    },
+                                    "capabilities": securityContextCapabilities,
                                     "readOnlyRootFilesystem": True,
                                 },
                                 "terminationMessagePath": "/dev/termination-log",
@@ -320,10 +336,7 @@ def _create_job_definition(self, job_id, namespace, pods, env):
                                 "resources": self.batch_engine_config.resources,
                                 "securityContext": {
                                     "allowPrivilegeEscalation": False,
-                                    "capabilities": {
-                                        "add": ["NET_BIND_SERVICE"],
-                                        "drop": ["ALL"],
-                                    },
+                                    "capabilities": securityContextCapabilities,
                                     "readOnlyRootFilesystem": False,
                                 },
                                 "terminationMessagePath": "/dev/termination-log",


Test patch: