Help us improve
Share bugs, ideas, or general feedback.
From cybersecurity-skills
Audits container images, Dockerfiles, Helm charts, Kustomize overlays, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks.
npx claudepluginhub briiirussell/cybersecurity-skills --plugin cybersecurity-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/cybersecurity-skills:container-auditThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Audit container images, Dockerfiles, Helm charts, Kustomize overlays, and Kubernetes manifests for misconfiguration, excessive privilege, exposed secrets, and runtime security gaps. Distinct from `cloud-audit` (cloud-provider IAM and managed services) and `dependency-audit` (package CVEs in the application). This skill is the container/orchestration layer between them.
Secures containerized apps with Docker hardening, image vulnerability scanning, Kubernetes pod security standards, network policies, RBAC, secrets management, and runtime protection.
<!-- AUTO-GENERATED by export-plugins.py — DO NOT EDIT -->
Review container security including image scanning, runtime policies, and supply chain integrity.
Share bugs, ideas, or general feedback.
Audit container images, Dockerfiles, Helm charts, Kustomize overlays, and Kubernetes manifests for misconfiguration, excessive privilege, exposed secrets, and runtime security gaps. Distinct from cloud-audit (cloud-provider IAM and managed services) and dependency-audit (package CVEs in the application). This skill is the container/orchestration layer between them.
FROM node:20@sha256:abc... not FROM node:20 (which can move)gcr.io/distroless/nodejs20, alpine (be aware of musl quirks), chainguard/*:latest — non-reproducible buildsFROM build AS builder → FROM runtime final stageFROM .*:latest, FROM .*:[0-9]+$ (tag without digest)--build-arg end up in image layers visible to anyone who pulls the image — use BuildKit secrets (--mount=type=secret) or runtime env vars insteadCOPY . . ships everything in the build context — .dockerignore should exclude .git, .env, node_modules, *.pem, .aws/, .ssh/ADD <url> follows redirects and disables checksum verification — prefer RUN curl ... && sha256sum -cARG .*KEY, ARG .*TOKEN, ARG .*SECRET, ENV .*=.*[A-Za-z0-9]{32,}, ADD httpUSER 1001 (or any non-zero UID) before CMDchmod 4755 SUID binaries in the final imageHEALTHCHECK defined so orchestrator can detect unhealthy containers/tmp or a declared volume)USER root (or absence of any USER directive), chmod 4755, apt-get install.*sudosecurityContext.runAsNonRoot: true and runAsUser set to a non-zero UIDsecurityContext.allowPrivilegeEscalation: falsesecurityContext.readOnlyRootFilesystem: true with explicit emptyDir mounts where the app needs to writesecurityContext.capabilities.drop: ["ALL"] then add only what's neededsecurityContext.privileged is never true in app workloads (Falco, kube-proxy, some CSI drivers are the rare legit exceptions)hostNetwork, hostPID, hostIPC all false — yes on these is "container can see / talk to the node"hostPath volumes — every one is a node-escape risk; review case by caseprivileged: true, runAsUser: 0, hostNetwork: true, hostPath:restricted profile via PSS admission, or equivalent via OPA Gatekeeper / Kyvernokube-system namespace running app codeNetworkPolicy exists for every namespace running app workloads — default-deny ingress AND egress, then allow specific podstls.crt / tls.key in K8s Secrets rotate--encryption-provider-config on kube-apiserver/proc/<pid>/environ, error reports, crash dumps)kind: Secret in Git with data: fields (base64-encoded values committed)ClusterRole with * verbs on * resources except cluster-admin (audit who's bound to it)ServiceAccount per workload, not shared "default" SAautomountServiceAccountToken: false on workloads that don't need API accesssystem:authenticated group are visible to every legitimate workload — almost always wrongverbs: ["*"], resources: ["*"], apiGroups: ["*"], system:authenticatedresources.requests and resources.limits set — missing limits = noisy neighbor + DoS surface (one pod can starve the node)LimitRange per namespace as a backstopResourceQuota per namespace prevents tenant-vs-tenant resource exhaustionimagePullPolicy: Always for :latest (you shouldn't use :latest, but if you do) — otherwise the node caches stale imagestrivy image, grype, docker scout cves. Must run on every build; advisories should not block but should surfaceexec, attach, port-forward events for incident responsekubectl exec access tracked — not free for any cluster-admin to silently shell into prod# All Dockerfiles in the repo + their first FROM line
git ls-files | grep -E '(^|/)Dockerfile(\.|$)' | xargs -I{} sh -c 'echo "==> {}"; grep ^FROM "{}"'
# Manifests missing securityContext
grep -rL "securityContext" --include="*.yaml" --include="*.yml" .
# Manifests with privileged containers
grep -rln "privileged: *true" --include="*.yaml" --include="*.yml" .
# Manifests with hostPath volumes
grep -rln "hostPath:" --include="*.yaml" --include="*.yml" .
# Secrets in Git (base64-encoded but readable)
grep -rln "kind: *Secret" --include="*.yaml" --include="*.yml" . | xargs grep -l "^data:"
# Image scan (Trivy)
trivy image --severity HIGH,CRITICAL --exit-code 0 <image>
# Manifest scan (Trivy)
trivy config --severity HIGH,CRITICAL .
# Cluster posture (kube-bench, run inside the cluster)
kube-bench run --targets master,node,policies
runAsNonRoot: true — verify the pod restarts cleanly and stays Running; if the image's ENTRYPOINT calls chown it'll crashloopkubectl run -it --rm debug ... curl); silent partial outages are common after default-deny rolloutreadOnlyRootFilesystem: true — verify the app doesn't write outside declared emptyDir mounts; log writes, PID files, and tmp files are common breakers# Container Security Audit
## Target: [cluster name / image registry / repo path]
## Date: [date]
### Summary
- Dockerfiles audited: N
- Manifests audited: N
- Cluster posture checks: pass / fail counts
### Findings
| ID | Severity | Category | Location | Issue |
|----|----------|----------|----------|-------|
### Per-finding detail
#### [SEVERITY] [Title]
**File:** `path/to/manifest.yaml:42`
**Category:** Dockerfile | Pod security | RBAC | NetworkPolicy | Secrets | Resource limits | Image policy | Runtime
**Description:** [what the issue is]
**Vulnerable config:**
```yaml
[snippet]
Remediation:
[fixed snippet]
Verification: [observed behavior proving the fix holds]
Disposition rule (Fixed / Deferred / Accepted Risk) matches `owasp-audit`.
## Boundaries
- Only audit clusters and registries the user provides or has authorization for
- Never `kubectl delete` or modify cluster state during an audit — read-only operations only (`get`, `describe`, `auth can-i`)
- For runtime evidence, prefer non-disruptive checks (a `kubectl run -it --rm` ephemeral debug pod) over modifying running workloads
- Refuse cluster-takeover scenarios — escalating from a found weakness to a full pivot is exploitation, not audit
- Flag low-confidence findings as "Potential" rather than confirmed
## References
- CIS Docker Benchmark
- CIS Kubernetes Benchmark
- NSA/CISA Kubernetes Hardening Guide
- Pod Security Standards (PSS) — restricted, baseline, privileged
- OWASP Docker Security Cheat Sheet
- OWASP Kubernetes Security Cheat Sheet
- MITRE ATT&CK for Containers