From cybersecurity-skills
Audits container images, Dockerfiles, Helm charts, Kustomize overlays, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks.
How 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.
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
npx claudepluginhub briiirussell/cybersecurity-skills --plugin cybersecurity-skillsSecures 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.