../_images/kup6s-icon-howto.svg

Configure security context

This guide shows you how to harden backend and frontend pods by setting a Kubernetes container security context through cdk8s-plone. Use it when your cluster enforces Pod Security Standards, when an admission webhook rejects permissive pods, or when you want to apply least-privilege defaults.

Prerequisites

  • A working Plone deployment using cdk8s-plone.

  • A Plone image that runs as a non-root user (the official plone/plone-backend and plone/plone-frontend images do).

  • Cluster knowledge of any namespace-level Pod Security Standards in effect.

Apply a baseline hardened context

Set securityContext on backend or frontend (or both).

import { Plone, PloneVariant } from '@bluedynamics/cdk8s-plone';

new Plone(chart, 'plone', {
  variant: PloneVariant.VOLTO,
  backend: {
    image: 'plone/plone-backend:6.1.3',
    securityContext: {
      runAsNonRoot: true,
      allowPrivilegeEscalation: false,
      capabilities: {
        drop: ['ALL'],
      },
    },
  },
  frontend: {
    image: 'plone/plone-frontend:16.0.0',
    securityContext: {
      runAsNonRoot: true,
      allowPrivilegeEscalation: false,
      capabilities: {
        drop: ['ALL'],
      },
    },
  },
});

These four settings satisfy the Kubernetes restricted Pod Security Standard for containers that do not need extra capabilities.

Pin the UID and GID

If your cluster requires explicit user and group IDs (for example, when you mount shared volumes), set them:

backend: {
  image: 'plone/plone-backend:6.1.3',
  securityContext: {
    runAsUser: 500,
    runAsGroup: 500,
    runAsNonRoot: true,
  },
}

The official Plone backend image already uses UID 500. Match that UID to keep file permissions consistent with the image.

Mount the root filesystem read-only

backend: {
  image: 'plone/plone-backend:6.1.3',
  securityContext: {
    runAsNonRoot: true,
    readOnlyRootFilesystem: true,
    allowPrivilegeEscalation: false,
    capabilities: {
      drop: ['ALL'],
    },
  },
}

Warning

A read-only root filesystem breaks any container that writes outside mounted volumes. Plone’s Zope writes temporary files; verify the pod stays Ready after rollout. Mount writable emptyDir volumes for /tmp and the Zope var/ directory through podAnnotations or the underlying Deployment patches if you hit EROFS errors.

Add a specific capability

When you must add a Linux capability, drop everything else first.

backend: {
  image: 'plone/plone-backend:6.1.3',
  securityContext: {
    runAsNonRoot: true,
    allowPrivilegeEscalation: false,
    capabilities: {
      add: ['SYS_PTRACE'],
      drop: ['ALL'],
    },
  },
}

Verify the rollout

# Generate manifests
cdk8s synth

# Confirm the securityContext appears on the pod template
grep -A 10 securityContext dist/*.yaml

# Apply and check pod status
kubectl apply -f dist/
kubectl rollout status deployment/<plone-backend-deployment> -n <namespace>

# Inspect the running container
kubectl exec -n <namespace> deployment/<plone-backend-deployment> -- id

A pod that fails to start with CreateContainerConfigError or permission denied usually points to a UID, capability, or read-only conflict.

See also