Skip to main content

Pod security

French version: ../pod-security.md.

Context applied by the chart​

Every chart pod (control plane, worker, migration, portal, LiteLLM, vLLM, multimodal workers) uses the eai.podSecurityContext and eai.containerSecurityContext helpers:

  • runAsNonRoot: true, runAsUser: 10001, runAsGroup: 10001, fsGroup: 10001;
  • seccompProfile: RuntimeDefault;
  • readOnlyRootFilesystem: true, with an emptyDir mounted on /tmp;
  • allowPrivilegeEscalation: false;
  • capabilities.drop: [ALL], NET_RAW included: a compromised pod cannot forge ARP or DNS packets to spoof a neighbour;
  • hostNetwork, hostPID, hostIPC explicitly false, no hostPath volume, no hostPort;
  • CPU and memory requests and limits on every container;
  • enableServiceLinks: false (no environment variables revealing the other Services).

automountServiceAccountToken: false on every pod and ServiceAccount, except the control plane Deployment: it creates the sandbox pods and their NetworkPolicies, so it needs its token. It is also the only pod allowed to reach the Kubernetes API (eai-deny-kube-apiserver).

Documented GPU exceptions​

ExceptionWorkloadJustification
emptyDir medium: Memory on /dev/shmvLLMNCCL and tensor parallelism exchange through shared memory; the size is bounded (sizeLimit)
model cache PVCvLLMweights preloaded, HF_HUB_OFFLINE=1, no download at runtime
eai-gpu namespace at baselinethird-party GPU imagessome vendor images (model servers, CUDA based images such as dcgm-exporter) run as UID 0 and cannot declare runAsNonRoot, which restricted refuses. baseline still forbids privileged containers, hostPath, host namespaces, hostPort and added dangerous capabilities. audit and warn stay at restricted
gpu-operator namespace at privilegedNVIDIA operatorthe driver, toolkit and device plugin install the kernel module and expose /dev/nvidia*; this namespace runs no platform code

The chart vLLM and worker pods keep the full restricted context; test_platform_security_manifests.py rejects any other exception.

Pod Security Admission​

deploy/cilium/namespaces.yaml (synced by Argo CD with deploy/cilium) labels the namespaces: pod-security.kubernetes.io/enforce=restricted for enterprise-ai, eai-data, eai-security, openbao, apisix; the sandbox namespace (eai-sandbox) is created by the chart at restricted.

Kyverno policies​

deploy/policies/kyverno/pod-network-security.yaml, in Enforce mode:

PolicyRules
eai-pod-securitydrop-all-capabilities, disallow-added-capabilities (never NET_RAW, only NET_BIND_SERVICE tolerated), require-seccomp, disallow-privileged, disallow-host-namespaces, disallow-host-path, disallow-host-ports
eai-service-account-tokensa pod on the default ServiceAccount must set automountServiceAccountToken: false
eai-image-provenanceoutside the Harbor eai and mirror projects (verified by cosign in cluster-policies.yaml and pinned by mutateDigest), an image must be referenced by digest
eai-restrict-service-exposureno externalIPs (CVE-2020-8554), no NodePort outside ingress and apisix

These policies complement cluster-policies.yaml (signatures, non root, read only root filesystem, limits, labels). Test cases live in deploy/policies/kyverno/tests:

kyverno test deploy/policies/kyverno/tests
helm template eai deploy/helm/enterprise-ai -f deploy/helm/enterprise-ai/values-onprem-gpu.yaml > /tmp/r.yaml
kyverno apply deploy/policies/kyverno/pod-network-security.yaml --resource /tmp/r.yaml