
Container Audit
- 116 installs
- 341 repo stars
- Updated May 27, 2026
- briiirussell/cybersecurity-skills
Container Audit is a Claude skill that audits Dockerfiles, container images, and Kubernetes manifests for misconfigurations, excessive privilege, and exposed secrets.
About
Container Audit reviews container images, Dockerfiles, Helm charts, and Kubernetes manifests for misconfiguration, excessive privilege, exposed secrets, and runtime risks. A developer or platform engineer uses it to harden the container and orchestration layer between cloud IAM and application dependencies. It provides checklists and grep patterns for base images, build-time exposure, pod security context, network policy, secrets, and RBAC.
- Dockerfile checklist for base-image pinning, build secrets, and non-root runtime
- Kubernetes checks for pod securityContext, NetworkPolicy, secrets, and RBAC
- Grep patterns for privileged: true, runAsUser: 0, and committed K8s Secrets
Container Audit by the numbers
- 116 all-time installs (skills.sh)
- Ranked #965 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
container-audit capabilities & compatibility
- Capabilities
- container security audit · security audit · kubernetes audit · secrets audit
- Works with
- docker · kubernetes
- Use cases
- security audit · devops
What container-audit says it does
Audit container images, Dockerfiles, Helm charts, Kustomize overlays, and Kubernetes manifests for misconfiguration, excessive privilege, exposed secrets, and runtime security gaps.
K8s Secrets are base64-encoded, NOT encrypted — by default they're plain bytes in etcd
Non-root user — `USER 1001` (or any non-zero UID) before `CMD`
npx skills add https://github.com/briiirussell/cybersecurity-skills --skill container-auditAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 116 |
|---|---|
| repo stars | ★ 341 |
| Last updated | May 27, 2026 |
| Repository | briiirussell/cybersecurity-skills ↗ |
What it does
Audit Dockerfiles, container images, and Kubernetes manifests for misconfigurations, excessive privilege, and exposed secrets.
Who is it for?
Hardening the container and Kubernetes layer for privilege, secrets, and network isolation
Skip if: Cloud-provider IAM and managed services (use cloud-audit) or application package CVEs (use dependency-audit)
When should I use this skill?
the user mentions container security, Dockerfile audit, Kubernetes or pod security, or image scanning
What you get
A hardened container and Kubernetes posture with pinned images, non-root runtime, network policies, and scoped RBAC.
- container and Kubernetes security findings with remediation
By the numbers
- Separate checklists for Dockerfile and Kubernetes manifests
- Checks Pod Security Standards restricted profile
- Flags Pod Security Policies removed in 1.25
Files
Container Audit — Docker & Kubernetes Security Review
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.
Scope the Audit
1. Inventory the surface — Dockerfiles, base images, registries, Helm charts, K8s manifests, Kustomize overlays, CI build pipelines that produce images 2. Identify the runtime — vanilla K8s, EKS, GKE, AKS, OpenShift, ECS Fargate, Cloud Run, Fly.io 3. Identify the network model — service mesh, ingress controller, default-deny vs default-allow 4. Identify the secret model — K8s Secrets (base64-only), External Secrets Operator, sealed-secrets, Vault, Doppler
Audit Checklist — Dockerfile
Base image & supply chain
- Pinned by digest, not tag —
FROM node:20@sha256:abc...notFROM node:20(which can move) - Distroless / minimal where possible —
gcr.io/distroless/nodejs20,alpine(be aware of musl quirks),chainguard/* - Not using
:latest— non-reproducible builds - Multi-stage builds discard build-time tooling —
FROM build AS builder→FROM runtimefinal stage - Grep for:
FROM .*:latest,FROM .*:[0-9]+$(tag without digest)
Build-time exposure
- Secrets passed via
--build-argend up in image layers visible to anyone who pulls the image — use BuildKit secrets (--mount=type=secret) or runtime env vars instead COPY . .ships everything in the build context —.dockerignoreshould exclude.git,.env,node_modules,*.pem,.aws/,.ssh/ADD <url>follows redirects and disables checksum verification — preferRUN curl ... && sha256sum -c- Grep for:
ARG .*KEY,ARG .*TOKEN,ARG .*SECRET,ENV .*=.*[A-Za-z0-9]{32,},ADD http
Runtime posture
- Non-root user —
USER 1001(or any non-zero UID) beforeCMD - No
chmod 4755SUID binaries in the final image - No unnecessary shells / package managers in the final stage — distroless / FROM scratch is the strong default
HEALTHCHECKdefined so orchestrator can detect unhealthy containers- Read-only root filesystem at runtime (set via K8s; verify nothing in the image writes outside
/tmpor a declared volume) - Grep for:
USER root(or absence of anyUSERdirective),chmod 4755,apt-get install.*sudo
Audit Checklist — Kubernetes manifests
Pod security
securityContext.runAsNonRoot: trueandrunAsUserset to a non-zero UIDsecurityContext.allowPrivilegeEscalation: falsesecurityContext.readOnlyRootFilesystem: truewith explicitemptyDirmounts where the app needs to writesecurityContext.capabilities.drop: ["ALL"]then add only what's neededsecurityContext.privilegedis nevertruein app workloads (Falco, kube-proxy, some CSI drivers are the rare legit exceptions)hostNetwork,hostPID,hostIPCallfalse— yes on these is "container can see / talk to the node"hostPathvolumes — every one is a node-escape risk; review case by case- Grep for:
privileged: true,runAsUser: 0,hostNetwork: true,hostPath:
Pod Security Standards (PSS) / admission
- Cluster enforces
restrictedprofile via PSS admission, or equivalent via OPA Gatekeeper / Kyverno - Pod Security Policies (deprecated since 1.21, removed in 1.25) are NOT what's enforcing this — confirm a current admission controller
- No workloads in the
kube-systemnamespace running app code
Network
NetworkPolicyexists for every namespace running app workloads — default-deny ingress AND egress, then allow specific pods- Missing NetworkPolicy = every pod can talk to every other pod on every port, including kube-apiserver and metadata service
- Service mesh (Istio, Linkerd) mTLS in STRICT mode for sensitive namespaces, not PERMISSIVE
- Ingress controllers terminate TLS properly; backend
tls.crt/tls.keyin K8s Secrets rotate
Secrets
- K8s Secrets are base64-encoded, NOT encrypted — by default they're plain bytes in etcd
- etcd encryption at rest enabled —
--encryption-provider-configon kube-apiserver - Workloads consume secrets via projected volumes, not environment variables (env vars leak via
/proc/<pid>/environ, error reports, crash dumps) - External Secrets Operator / Vault / sealed-secrets bridge so the Git repo never contains plaintext
- Grep for:
kind: Secretin Git withdata:fields (base64-encoded values committed)
RBAC
- No
ClusterRolewith*verbs on*resources exceptcluster-admin(audit who's bound to it) ServiceAccountper workload, not shared "default" SAautomountServiceAccountToken: falseon workloads that don't need API access- Bindings of
system:authenticatedgroup are visible to every legitimate workload — almost always wrong - Grep for:
verbs: ["*"],resources: ["*"],apiGroups: ["*"],system:authenticated
Resource limits
- Every container has
resources.requestsandresources.limitsset — missing limits = noisy neighbor + DoS surface (one pod can starve the node) LimitRangeper namespace as a backstopResourceQuotaper namespace prevents tenant-vs-tenant resource exhaustion
Image policy
imagePullPolicy: Alwaysfor:latest(you shouldn't use :latest, but if you do) — otherwise the node caches stale images- Cluster-level policy that all images come from approved registries (your own + a small allow-list); enforced via Gatekeeper / Kyverno / image-policy-webhook
- Image signature verification — cosign + sigstore policy controller, or Notary v2
Audit Checklist — runtime
- Image scanning in CI —
trivy image,grype,docker scout cves. Must run on every build; advisories should not block but should surface - Runtime detection — Falco / Tracee / Tetragon catches "shell spawned in a pod that has never opened a shell" patterns
- Audit logs enabled — kube-apiserver audit log captures
exec,attach,port-forwardevents for incident response kubectl execaccess tracked — not free for any cluster-admin to silently shell into prod
Useful one-liners
# 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,policiesVerify Fixes at Runtime
runAsNonRoot: true— verify the pod restarts cleanly and stays Running; if the image'sENTRYPOINTcallschownit'll crashloop- NetworkPolicy default-deny — verify legitimate traffic still works (run an in-cluster
kubectl run -it --rm debug ... curl); silent partial outages are common after default-deny rollout readOnlyRootFilesystem: true— verify the app doesn't write outside declaredemptyDirmounts; log writes, PID files, and tmp files are common breakers- Image-policy enforcement — try to deploy an unsigned / off-list image; verify admission rejects it
Report Format
# 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:**[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 deleteor 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 --rmephemeral 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
Related skills
FAQ
How does it differ from cloud-audit?
cloud-audit covers cloud-provider IAM and managed services; container-audit is the container and orchestration layer, including Dockerfiles, pods, NetworkPolicy, and RBAC.
Are K8s Secrets encrypted?
No, K8s Secrets are base64-encoded, not encrypted, so the skill checks for etcd encryption at rest and projected-volume consumption instead of env vars.