Skip to content
Security
Skill

/container-audit

Audit container images, Dockerfiles, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks. Use when the user mentions 'container security,' 'Docker security,' 'Dockerfile audit,' 'Kubernetes security,' 'K8s security,' 'pod

BOOST
From plugin
cybersecurity-skills
42229 skills
Install
$ npx -y skills add briiirussell/cybersecurity-skills --skill container-audit --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/container-audit

Context preview

The summary Claude sees to decide when to auto-load this skill.

Audit container images, Dockerfiles, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks. Use when the user mentions 'container security,' 'Docker security,' 'Dockerfile audit,' 'Kubernetes security,' 'K8s security,' 'pod

SKILL.md

container-audit.SKILL.md
name: container-audit
description: "Audit container images, Dockerfiles, and Kubernetes manifests for misconfigurations, excessive privileges, exposed secrets, and runtime risks. Use when the user mentions 'container security,' 'Docker security,' 'Dockerfile audit,' 'Kubernetes security,' 'K8s security,' 'pod security,' 'container hardening,' 'kubectl audit,' 'image scanning,' 'distroless,' 'rootless containers,' 'pod security policy,' 'pod security standards,' 'PSS,' 'network policy,' 'OPA Gatekeeper,' 'Kyverno,' 'runtime security,' or needs to review container or orchestration security."
allowed-tools: Bash, Read, Write, Grep, Glob, WebSearch

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...` not `FROM 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 runtime` final stage
  • Grep for: `FROM .*:latest`, `FROM .*:[0-9]+$` (tag without digest)

Build-time exposure

  • Secrets passed via `--build-arg` end 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 — `.dockerignore` should exclude `.git`, `.env`, `node_modules`, `*.pem`, `.aws/`, `.ssh/`
  • `ADD <url>` follows redirects and disables checksum verification — prefer `RUN 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) before `CMD`
  • No `chmod 4755` SUID binaries in the final image
  • No unnecessary shells / package managers in the final stage — distroless / FROM scratch is the strong default
  • `HEALTHCHECK` defined so orchestrator can detect unhealthy containers
  • Read-only root filesystem at runtime (set via K8s; verify nothing in the image writes outside `/tmp` or a declared volume)
  • Grep for: `USER root` (or absence of any `USER` directive), `chmod 4755`, `apt-get install.*sudo`

Audit Checklist — Kubernetes manifests

Pod security

  • `securityContext.runAsNonRoot: true` and `runAsUser` set to a non-zero UID
  • `securityContext.allowPrivilegeEscalation: false`
  • `securityContext.readOnlyRootFilesystem: true` with explicit `emptyDir` mounts where the app needs to write
  • `securityContext.capabilities.drop: ["ALL"]` then add only what's needed
  • `securityContext.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 case
  • Grep for: `privileged: true`, `runAsUser: 0`, `hostNetwork: true`, `hostPath:`

Pod Security Standards (PSS) / admission

  • Cluster enforces `restricted` profile 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-system` namespace running app code

Network

  • `NetworkPolicy` exists 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.key` in 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-config` on 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: Secret` in Git with `data:` fields (base64-encoded values committed)

RBAC

  • No `ClusterRole` with `*` verbs on `*` resources except `cluster-admin` (audit who's bound to it)
  • `ServiceAccount` per workload, not shared "default" SA
  • `automountServiceAccountToken: false` on workloads that don't need API access
  • Bindings of `system:authenticated` group are visible to every legitimate workload — almost always wrong
  • Grep for: `verbs: ["*"]`, `resources: ["*"]`, `apiGroups: ["*"]`, `system:authenticated`

Resource limits

  • Every container has `resources.requests` and `resources.limits` set — missing limits = noisy neighbor + DoS surface (one pod can starve the node)
  • `LimitRange` per namespace as a backstop
  • `ResourceQuota` per namespace prevents tenant-vs-tenant resource exhaustion
Read more
Ships withcybersecurity-skills

A collection of cybersecurity skills for AI coding agents. The AI does the heavy lifting; you bring the context about your stack and your priorities.

Get the whole plugin

Other skills on cybersecurity-skills.