Django Kubernetes Security Checklist
A security checklist for Django on Kubernetes: non-root containers with read-only filesystems, Pod Security Standards, minimal RBAC and service account tokens, secrets from a manager, NetworkPolicies, image scanning and signing, patched nodes, and audit logging.
Problem statement
Running Django on Kubernetes adds a layer of infrastructure with its own attack surface: pods running as root, service account tokens that can talk to the API server, secrets readable by anyone with namespace access, flat networks, and images nobody scanned. A vulnerability in a Python dependency can turn into cluster-wide compromise if these defaults are left in place. This checklist hardens the Kubernetes side of a Django deployment.
- Run containers as non-root with a read-only root filesystem, no privilege escalation, and dropped capabilities.
- Enforce the
restrictedPod Security Standard on application namespaces. - Disable automatic service account token mounting for Django pods unless they call the Kubernetes API.
- Load secrets from a secrets manager (External Secrets, CSI driver) and enable encryption at rest for Kubernetes Secrets.
- Apply NetworkPolicies, scan and sign images, keep nodes and the control plane patched, and enable audit logs.
Checklist
Pod and container hardening
securityContext:runAsNonRoot: true,allowPrivilegeEscalation: false,readOnlyRootFilesystem: true,capabilities.drop: ["ALL"],seccompProfile.type: RuntimeDefault.- Writable paths (
/tmp) mounted asemptyDir; logs to stdout; media in object storage. - Namespaces labeled
pod-security.kubernetes.io/enforce: restricted. - Resource requests and limits set so a compromised pod cannot starve the node.
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities: { drop: ["ALL"] }
seccompProfile: { type: RuntimeDefault }
Identity and access
automountServiceAccountToken: falseon Django and Celery pods that do not use the Kubernetes API.- Dedicated service accounts per workload; RBAC roles minimal and namespaced; no
cluster-adminfor CI. - Human access via SSO with short-lived credentials;
kubectl execinto production restricted and audited. - Cloud workload identity (IRSA, GKE Workload Identity, Azure workload identity) instead of static cloud keys.
Secrets
- Secrets synced from a secrets manager (External Secrets Operator, Secrets Store CSI driver), not committed to git.
- etcd encryption at rest for Secrets enabled (default on most managed clusters; verify).
- RBAC prevents broad
get/list secretspermissions; reading secrets is limited to workloads and admins. - Rotation process tested for
SECRET_KEY, database credentials, and API keys.
Network
- Default-deny NetworkPolicies with explicit allows for ingress controller, database, Redis, DNS, and required APIs.
- Database and cache not exposed outside the cluster or VPC.
- Ingress with TLS, modern ciphers, and WAF or rate limiting in front of public endpoints.
Supply chain and cluster
- Images built in CI from pinned base images, scanned (Trivy, Grype), and signed (Cosign); admission policy verifies signatures.
- Images referenced by digest or immutable tags; no
latest. - Control plane and node pools on supported, patched versions; automatic node upgrades in maintenance windows.
- Kubernetes audit logs enabled and retained; alerts on suspicious API activity (exec into pods, secret reads, RBAC changes).
Explanation
Kubernetes security works in layers: the container's privileges, the pod's identity, the secrets it can read, the network it can reach, the images it runs, and the cluster underneath. A Django app compromised through a dependency vulnerability gains whatever its pod can do. Running non-root with a read-only filesystem limits local damage; removing API tokens and minimizing RBAC stops escalation into the cluster; NetworkPolicies limit lateral movement; secrets management and supply chain controls protect credentials and code integrity.
Edge cases / notes
- Read-only filesystems. Python writes
.pycfiles and Django may write temp files; setPYTHONDONTWRITEBYTECODE=1and mount/tmp. - Init containers. Migration Jobs and init containers need the same hardening as the main pods.
- Managed add-ons. Cloud provider agents may need privileges; isolate them in their own namespaces.
Next steps
- Cover reliability too with the Django Kubernetes Production Checklist.
- Restrict traffic with Restrict Django Pod Traffic With NetworkPolicies.
- Sync secrets with Use External Secrets Operator With Django.
FAQ
Should Django pods run as root?
No. Run as a non-root user with no privilege escalation and dropped capabilities.
Does a Django pod need a service account token?
Usually not. Disable automounting unless the app calls the Kubernetes API.
Are Kubernetes Secrets secure?
They are base64-encoded, not encrypted, unless etcd encryption is enabled. Source them from a manager and restrict access with RBAC.
How do I stop unsigned images from running?
Sign images in CI with Cosign and enforce verification with an admission controller.