All 26 checks with why-it-matters prose, severity, and cross-references to related audits.
Floating tags like `latest` are mutable — the same tag can silently deliver a different, compromised image on the next build. An attacker who poisons an upstream image layer (CWE-1357, supply-chain attack) gains code execution in your container without triggering any diff in your repository. NIST 800-53 CM-14 and SLSA L3 both require provenance guarantees that floating tags cannot provide. CIS Docker Benchmark 5.31 flags this as a supply-chain control. SHA-256 digest pinning is the only mechanism that makes each build deterministic and independently verifiable.
Why this severity: Critical because a poisoned base image executes attacker-controlled code in every container instance derived from it, with no application-level defense possible.
infrastructure-hardening.container-image-security.from-official-pinnedSee full patternContainers running as root (UID 0) violate the principle of least privilege (NIST 800-53 AC-6, CWE-250) and collapse the host boundary if any container escape vulnerability is exploited. A root container with a kernel exploit gains full control of the host node — every other workload on that node is compromised. CIS Docker 4.1 and CIS Kubernetes 5.2.6 both mandate non-root execution. The blast radius of a runtime compromise is bounded only when the container process has no privilege to exercise outside its own namespace.
Why this severity: Critical because a container running as root combined with any container-escape vulnerability grants full host node access, compromising all co-located workloads.
infrastructure-hardening.container-image-security.non-root-userSee full patternSecrets baked into Docker image layers are permanently readable by anyone with registry pull access — including future employees, CI systems, and compromised tokens (OWASP A02, CWE-540). Docker layer history exposes every `ARG`, `ENV`, and `RUN` instruction even after a subsequent `RUN unset` — the value persists in the lower layer. NIST 800-53 SC-28 requires protection of information at rest; credentials in registry layers violate that control and are disclosed with every `docker history` command. This is one of the most common paths to credential exposure in containerized environments.
Why this severity: Critical because credentials baked into image layers are exfiltrated by anyone with registry read access — no runtime exploit required.
infrastructure-hardening.container-image-security.no-secrets-in-layersSee full patternSingle-stage Docker builds include compilers, package managers, build caches, test fixtures, and development dependencies in the final production image. Every extra binary is an additional attack surface — a compromised container with build tools installed can compile exploits, exfiltrate files, or pivot to other services more easily. NIST 800-53 CM-7 requires systems to provide only essential capabilities. CIS Docker 4.9 explicitly requires minimal image construction. Images over 500 MB also inflate registry storage costs and slow deployment velocity at scale.
Why this severity: High because bloated images increase attack surface by including compilers and dev tools that have no role in production and enable post-compromise lateral movement.
infrastructure-hardening.container-image-security.multi-stage-buildSee full patternContainer images accumulate CVEs between builds — a base image pinned three months ago may carry critical kernel or libc vulnerabilities exploitable at runtime (NIST 800-53 SI-3, CWE-1357). Without automated scanning in CI/CD, vulnerable images reach production silently. SSDF 800-218 RV.1.3 requires continuous vulnerability monitoring of software components. CIS Docker 4.7 mandates scanning. A pipeline that scans but allows critical findings to pass with `--exit-code 0` provides no protection — the gate must block deployment when high or critical CVEs are present.
Why this severity: High because unscanned images deliver known-CVE code to production silently, and most container exploits target CVEs that public scanners would have caught before deployment.
infrastructure-hardening.container-image-security.image-scanningSee full patternPlaintext HTTP exposes session tokens, API keys, and user credentials to passive network interception — any attacker on the same network segment can harvest credentials in seconds (CWE-319, OWASP A02). NIST 800-53 SC-8 requires transmission confidentiality for all authenticated sessions. CIS Kubernetes 5.4.1 mandates TLS at ingress. Beyond credential theft, transport without TLS enables active MITM attacks where responses are modified in transit — undermining the integrity of every API response the client trusts.
Why this severity: High because cleartext transmission of authentication tokens enables passive credential harvesting with no active exploit required — any network observer captures sessions.
infrastructure-hardening.network-tls.tls-enforcedSee full patternAn expired TLS certificate produces browser warnings that users train themselves to click through — or it breaks service entirely, causing an outage with no security justification. Manual certificate rotation fails at scale: teams forget expiry dates, renewal windows get missed during vacations, and a 90-day Let's Encrypt cert can silently expire over a long weekend. NIST 800-53 SC-17 requires certificate management controls. CWE-295 covers improper certificate validation. Automated renewal removes human failure from a process that must succeed on a strict calendar.
Why this severity: High because a missed manual renewal causes an immediate service outage or breaks TLS validation for all clients, with no grace period after expiry.
infrastructure-hardening.network-tls.cert-auto-renewalSee full patternWithout NetworkPolicies, any compromised pod in your cluster can initiate connections to any other pod or external service — an attacker who owns the frontend container can directly query your database, scrape environment variables from other pods, or exfiltrate data to an external server. NIST 800-53 SC-7 and AC-4 require network segmentation and information flow enforcement. CIS Kubernetes 5.3.2 mandates network policies. Default Kubernetes networking is flat — every pod can reach every other pod by default, which is the opposite of least-privilege.
Why this severity: High because flat cluster networking means a single compromised pod has unrestricted lateral movement to databases, secret stores, and control plane endpoints.
infrastructure-hardening.network-tls.network-policiesSee full patternWildcard verbs (`verbs: ['*']`) or `cluster-admin` bindings grant a service account the ability to read secrets, delete deployments, modify RBAC rules, or escalate its own privileges — effectively root access on the cluster (CWE-284, OWASP A01). NIST 800-53 AC-6 requires least-privilege access control. CIS Kubernetes 5.1.1 explicitly prohibits wildcard verbs and cluster-admin bindings for workload service accounts. A compromised pod with `cluster-admin` can exfiltrate every secret in the cluster within seconds.
Why this severity: High because a service account bound to cluster-admin gives any pod-level compromise full cluster control — secret exfiltration, deployment manipulation, and privilege persistence are all trivially achievable.
infrastructure-hardening.access-control-rbac.rbac-minimalSee full patternA privileged container (`securityContext.privileged: true`) has direct access to the host kernel, all devices, and the host network namespace — it is functionally equivalent to running as root on the node itself (CWE-250). Any exploit in a privileged container breaks out of containment immediately. NIST 800-53 CM-7 requires minimal functionality. CIS Kubernetes 5.2.1 prohibits privileged containers. Even when a container has a legitimate need for elevated access (e.g., packet capture), specific capabilities (`NET_ADMIN`, `NET_RAW`) are always preferable to blanket privilege.
Why this severity: Medium because privileged mode breaks container isolation entirely, but exploitation still requires a separate code execution path within the container first.
infrastructure-hardening.access-control-rbac.no-privileged-containersSee full patternA writable root filesystem allows malware dropped into a container to persist — modified binaries, installed backdoors, and written cron jobs survive across request handling even if the attacker's initial vector closes. NIST 800-53 CM-7 requires containers to provide only essential functionality. CIS Kubernetes 5.2.3 mandates read-only root filesystems for stateless workloads. Most stateless API servers and web frontends have zero legitimate need to write to the root filesystem at runtime — only log paths and temp directories require writability, and both can be served by emptyDir volumes.
Why this severity: Medium because a writable root filesystem allows an attacker with code execution to persist modifications across requests, but direct exploitation still requires a separate initial compromise.
infrastructure-hardening.access-control-rbac.read-only-filesystemSee full patternKubernetes Secrets stored without encryption at rest are base64-encoded plaintext in etcd — any operator with etcd access, a backup file, or an `etcd snapshot` command can decode every database password and API key in the cluster (CWE-312, OWASP A02). NIST 800-53 SC-28 requires encryption of data at rest. Secrets checked into ConfigMaps are worse — they appear in `kubectl get configmap -o yaml` with no access differentiation from application configuration. A hardcoded credential in a manifest that enters git history is exposed to every developer, CI system, and repository fork for the lifetime of the repo.
Why this severity: Medium because etcd encryption at rest is often disabled by default, making Kubernetes Secrets accessible to anyone with cluster backup or etcd read access without application-layer attack.
infrastructure-hardening.access-control-rbac.secrets-encryptedSee full patternWithout Kubernetes audit logging, there is no record of who accessed secrets, which pods were created, or when RBAC permissions were changed — post-incident forensics become guesswork (NIST 800-53 AU-2, AU-12). Adversaries routinely enumerate cluster resources, read secrets, and create privileged pods during an attack, then clean up their traces. Audit logs are the only evidence of these actions. CIS Kubernetes 3.2.1 mandates audit policy configuration. An audit policy that covers fewer than 3 event categories misses either authentication failures or RBAC denials — the two most actionable security signals in a cluster.
Why this severity: Medium because absent audit logs make post-incident forensics impossible, but the gap is detected during investigation rather than enabling direct data exfiltration.
infrastructure-hardening.monitoring-incident-response.audit-loggingSee full patternOpen egress to `0.0.0.0/0` means a compromised pod can exfiltrate data to any external server, download attacker tooling, or call command-and-control infrastructure — the container boundary provides zero containment for outbound traffic (NIST 800-53 SC-7, AC-4). Most production workloads communicate with a small, predictable set of destinations: a database, a few external APIs, and the Kubernetes control plane. Default Kubernetes networking permits unrestricted egress, so without explicit NetworkPolicy egress rules, a compromised pod has an outbound channel to the public internet from inside your cluster perimeter.
Why this severity: Medium because unrestricted egress enables data exfiltration and C2 communication from compromised containers, but requires initial code execution within the pod first.
infrastructure-hardening.monitoring-incident-response.egress-restrictedSee full patternUnsigned container images can be silently replaced in a registry — an attacker who gains push access to a registry can swap a legitimate image for a malicious one with the same tag, and every subsequent deployment pulls the compromised image without any cluster-level detection (CWE-494, NIST 800-53 CM-14, SLSA L3). Image signing with Cosign or Docker Content Trust creates a cryptographically verifiable chain from the image back to the CI system that built it. SSDF 800-218 PS.2.1 requires build provenance. Without admission webhook enforcement, signing alone is advisory — images can still be deployed without verification.
Why this severity: Low because unsigned image exploitation requires registry write access as a prerequisite, making it a targeted rather than opportunistic attack vector.
infrastructure-hardening.monitoring-incident-response.image-signingSee full patternWithout DNSSEC, DNS responses for your domain can be spoofed by attackers on the same network path — a forged A record redirects users to an attacker-controlled server that serves your site's login page to harvest credentials (NIST 800-53 SC-20). Without DNS query logging, there is no visibility into what domains cluster workloads are resolving — a key signal for detecting C2 communication and data exfiltration via DNS tunneling (NIST 800-53 AU-12). CIS DNS 3.1 requires both controls. CoreDNS logs are disabled by default in most Kubernetes deployments.
Why this severity: Low because DNS spoofing requires a network-level position between the resolver and authoritative server, limiting exploitation to targeted rather than remote attacks.
infrastructure-hardening.monitoring-incident-response.dns-securitySee full patternA private registry without ImagePullSecrets or IAM-based authentication is either fully open (defeating the purpose of a private registry) or relying on node-level credentials that are shared across all workloads on the node (CWE-522, NIST 800-53 IA-5). Credentials that are never rotated become permanent exfiltration targets — a token from 200 days ago likely has broader permissions than current registry access policies intend. CIS Kubernetes 5.4.1 requires authenticated access to private registries. Workload-level credentials scoped to specific registries and rotated on a schedule are the only defensible model.
Why this severity: Low because the attack path requires knowing the registry endpoint and having a network route to it, making exploitation dependent on prior reconnaissance.
infrastructure-hardening.monitoring-incident-response.image-pull-credentialsSee full patternWithout liveness and readiness probes, Kubernetes has no signal about whether your application is healthy — it routes traffic to pods that are stuck in initialization, deadlocked, or silently broken, and it never restarts containers that have reached a bad state without crashing (CIS Kubernetes 5.5.1). Probes with unrealistic thresholds (`timeoutSeconds` exceeding `periodSeconds`) guarantee probes always fail, defeating their purpose. A missing readiness probe means traffic arrives before the application finishes startup, producing a burst of 502 errors that users experience as downtime.
Why this severity: Low because missing probes degrade availability and mask application failures, but do not directly expose data or allow unauthorized access.
infrastructure-hardening.monitoring-incident-response.probes-configuredSee full patternContainers without resource limits can consume unbounded CPU and memory — a runaway process, a traffic spike, or a memory leak starves other pods on the same node, triggering cascading OOM kills and node instability (CIS Kubernetes 5.7.4, ISO 25010 performance efficiency). Without resource requests, the Kubernetes scheduler has no data for placement decisions, leading to uneven node utilization and unexpected evictions under load. A single container with no memory limit can consume all memory on a node and bring down unrelated production workloads.
Why this severity: Low because unbounded resource consumption primarily causes availability impact through node exhaustion rather than enabling direct data access or privilege escalation.
infrastructure-hardening.monitoring-incident-response.resource-limitsSee full patternWithout seccomp or AppArmor profiles, containers can make any Linux system call — including `ptrace`, `mount`, `kexec`, and others that have no role in application logic but are used in known container escape exploits (NIST 800-53 CM-7, CIS Kubernetes 5.7.2/5.7.3). Seccomp `RuntimeDefault` blocks over 300 system calls not used by typical applications, reducing the kernel attack surface measurably. `Unconfined` profiles explicitly disable all restrictions and are categorically worse than the default — any container with `Unconfined` is actively regressing security below Kubernetes defaults.
Why this severity: Low because missing runtime profiles leave kernel attack surface exposed, but exploitation requires a known kernel syscall vulnerability as a prerequisite.
infrastructure-hardening.monitoring-incident-response.runtime-security-policySee full patternPod Security Standards (PSS) provide namespace-level policy enforcement that is evaluated before pod admission — without them, a misconfigured or malicious workload can deploy privileged containers, run as root, or mount host paths regardless of what individual securityContext fields are set (NIST 800-53 AC-3, CIS Kubernetes 5.2.1/5.2.6). PSS `restricted` blocks the entire class of misconfigurations — running as root, privilege escalation, host namespaces — at the namespace boundary. Individual securityContext checks on Deployments are necessary but not sufficient; without PSS, nothing prevents a developer from removing those fields.
Why this severity: Low because PSS enforcement is a defense-in-depth control — its absence allows privileged pod deployment, but exploitation requires developer or CI-level cluster access.
infrastructure-hardening.monitoring-incident-response.pod-security-standardsSee full patternSSH port 22 exposed in a production container provides a persistent shell entry point for brute-force and credential-stuffing attacks — every host scanner on the public internet probes port 22 continuously (CWE-284, NIST 800-53 CM-7). A container with sshd installed adds unnecessary attack surface: the application has no need for interactive sessions, and any credential compromise or key leak provides direct OS access bypassing all application-layer controls. CIS Docker 5.6 explicitly prohibits SSH in containers. Kubernetes provides `kubectl exec` as the authenticated, audited alternative for debugging.
Why this severity: Low because SSH exposure requires a credential or key compromise to pivot to shell access, but the port being open makes brute-force and credential-stuffing attacks automatic.
infrastructure-hardening.monitoring-incident-response.no-ssh-rdp-exposedSee full patternAn application served without CDN or WAF absorbs every request directly — a DDoS attack that exceeds origin capacity takes down the service entirely, and malicious bots, scrapers, and credential stuffers operate without any filtering layer. NIST 800-53 SC-5 requires DoS protection; SI-3 requires malicious code protection at entry points. CIS AWS 2.5 requires WAF attachment to CloudFront distributions. Geo-blocking and bot detection are particularly relevant for AI-built projects whose attack surfaces are often discovered quickly via passive DNS enumeration.
Why this severity: Info because CDN/WAF absence increases vulnerability to volumetric attacks and bots, but direct exploitation still requires finding and hitting origin endpoints without WAF interception.
infrastructure-hardening.monitoring-incident-response.cdn-waf-protectionSee full patternLogs written only to stdout and discarded when a pod restarts leave no forensic trail for incidents — there is no record of which requests preceded a data breach, no timestamp evidence for compliance audits, and no visibility into error patterns that precede outages (NIST 800-53 AU-3, AU-9). CIS Kubernetes 3.2.2 requires log aggregation and forwarding. Missing trace IDs means individual requests cannot be correlated across service boundaries, turning a multi-service investigation into manual log grep archaeology. 30-day retention is the minimum threshold for detecting slow-burn attacks that unfold over weeks.
Why this severity: Info because absent centralized logging does not directly expose data, but makes post-incident forensics and compliance audit responses impossible.
infrastructure-hardening.monitoring-incident-response.centralized-loggingSee full patternInfrastructure and application metrics tell you CPU is high — security alerting tells you someone is trying to escalate privileges. Without alerts on failed authentication bursts, RBAC denials, or unexpected egress connections, active attacks proceed silently through your cluster until data has already left (NIST 800-53 SI-4, AU-6). CIS Kubernetes 3.2.1 requires audit logging and alert routing. A Prometheus instance with only CPU/memory/disk alerts is operationally useful but security-blind — the two alert categories are not interchangeable.
Why this severity: Info because absent security alerting means active attacks are not detected in real-time, but the gap enables longer dwell time rather than direct exploitation.
infrastructure-hardening.monitoring-incident-response.alerting-configuredSee full patternAn undocumented disaster recovery process is an untested one — and an untested recovery process will fail at the worst possible moment. Without explicit RTO and RPO targets, there is no definition of success during a recovery, no basis for SLA commitments, and no mechanism to detect that backups are unrestorable before they are needed (NIST 800-53 CP-2, CP-4, ISO 27001 A.5.30). CIS AWS 2.1.1 requires documented recovery procedures. The most common failure mode is not missing backups but unencrypted or untested backups that cannot be restored under real incident conditions.
Why this severity: Info because the absence of DR procedures does not expose data directly, but it guarantees extended outages and potential permanent data loss when an incident does occur.
infrastructure-hardening.monitoring-incident-response.disaster-recoverySee full patternRun this audit in your AI coding tool (Claude Code, Cursor, Bolt, etc.) and submit results here for scoring and benchmarks.
Open Infrastructure Hardening Audit