Skip to content

Configuring Pod Security Contexts

The Contain Platform enforces the Kubernetes Restricted Pod Security Standard by default. This is a critical security measure to protect all workloads running on the platform.

This means that any Deployment, StatefulSet, or other workload you deploy must include a specific securityContext configuration. If your pod's specification does not meet these minimum requirements, it will be rejected by the cluster's admission controller, and your pods will not be created.

This guide provides the mandatory instructions for configuring your workloads to meet these requirements.

Manually Configuring a Deployment

If you are writing your own deployment manifests, you must add a securityContext at both the pod level (spec.template.spec) and the container level (spec.template.spec.containers[]).

Before: A Non-Compliant Deployment

Without any security context, a simple deployment like the one below will be rejected by the platform.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-insecure
spec:
  # ...
  template:
    # ...
    spec:
      containers:
      - image: nginxinc/nginx-unprivileged:1.20
        name: my-app

After: A Compliant Deployment

To make this deployment compliant, you must add the required fields:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-secure
spec:
  # ...
  template:
    # ...
    spec:
      # 1. Add the Pod-level Security Context
      securityContext:
          runAsNonRoot: true
          runAsUser: 1000
          runAsGroup: 3000
          fsGroup: 2000
      containers:
      - image: nginxinc/nginx-unprivileged:1.20
        name: my-app
        # 2. Add the Container-level Security Context
        securityContext:
          allowPrivilegeEscalation: false
          capabilities:
            drop:
              - "ALL"

Required Fields Explained

  • Pod (spec.securityContext)
    • runAsNonRoot: true: Prevents the container from starting as the root user.
    • runAsUser / runAsGroup: Specifies the user and group ID the container process will run as.
    • fsGroup: Specifies a supplemental group that has access to volumes.
  • Container (securityContext)
    • allowPrivilegeEscalation: false: Prevents a process from gaining more privileges than its parent.
    • capabilities: { drop: ["ALL"] }: Drops all Linux capabilities, adhering to the principle of least privilege.

Patching Third-Party Helm Charts

Many public Helm charts do not meet these strict security requirements out of the box. You cannot simply deploy them as-is.

The platform's GitOps toolkit (Flux) provides a powerful mechanism called postRenderers that allows you to patch a Helm chart's output before it is applied to the cluster. This is the recommended way to make third-party charts compliant.

Example: Patching a Redis Helm Chart

In this example, we deploy the Bitnami Redis chart, which by default does not have the required security context. We use a postRenderers block in the HelmRelease manifest to apply a Kustomize strategic merge patch.

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: redis
spec:
  chart:
    spec:
      chart: redis
      version: 18.10.1 # Use a specific version
      sourceRef:
        kind: HelmRepository
        name: bitnami
        namespace: netic-gitops-system
  # Add this block to patch the rendered Helm templates
  postRenderers:
    - kustomize:
        patchesStrategicMerge:
          # Patch for the Redis master StatefulSet
          - apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: redis-master
            spec:
              template:
                spec:
                  securityContext:
                      runAsUser: 1001
                      runAsGroup: 1001
                      fsGroup: 1001
                  containers:
                    - name: redis
                      securityContext:
                        runAsUser: 1001
                        allowPrivilegeEscalation: false
                        capabilities:
                          drop:
                            - "ALL"
          # Patch for the Redis replicas StatefulSet
          - apiVersion: apps/v1
            kind: StatefulSet
            metadata:
              name: redis-replicas
            spec:
              template:
                spec:
                  securityContext:
                      runAsUser: 1001
                      runAsGroup: 1001
                      fsGroup: 1001
                  containers:
                    - name: redis
                      securityContext:
                        runAsUser: 1001
                        allowPrivilegeEscalation: false
                        capabilities:
                          drop:
                            - "ALL"

This HelmRelease will first render the standard Redis chart and then apply your patches, injecting the mandatory securityContext blocks into the final manifests that are deployed to the cluster.