agentsclimarketplace

Dockerfile hardening

Skill Hayatelin/devsecops-skills/skills/dockerfile-hardening

A security skills pack for Claude Code, Cursor, Codex and Gemini CLI: secrets pre-flight, dependency audit, secret rotation, STRIDE threat modeling, secure code review, Dockerfile hardening and env hygiene.

Install
npx -y skills add Hayatelin/devsecops-skills --skill dockerfile-hardening

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Harden a Dockerfile / container image against common misconfigurations. Trigger when the user says "harden this Dockerfile", "is my container secure", "review my Docker image", or when adding/editing a Dockerfile or container build before shipping.

SKILL.md

3.5 KB, as published. Nobody here has run it

When to use

  • Writing or reviewing a Dockerfile, Containerfile, or container build before it goes to a registry or production.
  • The user asks "is this image secure?" or wants a before/after hardening pass.
  • After a base-image bump or when an image scan (Trivy/Grype) flags issues.

Process

  1. Read the Dockerfile and note the base image, what runs as root, how secrets are handled, and the layer structure.
  2. Apply the checklist below, top to bottom.
  3. Produce a before/after Dockerfile so the change is reviewable.
  4. Recommend a scan to confirm: trivy image <tag> (or grype <tag>) and hadolint Dockerfile for lint.
  5. Verify the image still builds and runs after hardening.

Checklist

  • Non-root user — create and USER appuser; don't run as root. Use a numeric UID for k8s runAsNonRoot.
  • Pinned base image by digestFROM python:3.12-slim@sha256:..., not :latest. Prefer minimal bases (slim, distroless, alpine) to shrink attack surface.
  • Multi-stage build — build deps in a builder stage; copy only artifacts into a lean runtime stage. Keeps compilers/secrets out of the final image.
  • No secrets in layers — never COPY .env, never ARG/ENV a secret (it persists in history). Use BuildKit secret mounts: RUN --mount=type=secret,id=token ....
  • .dockerignore — exclude .git, .env, secrets, node_modules, build cruft so they never enter the context.
  • Minimal layers & cleanup — combine RUN steps; clean package caches in the same layer (rm -rf /var/lib/apt/lists/*); no leftover temp files.
  • Pin package versions — pin apt/pip/npm versions for reproducibility; copy lockfiles and install from them.
  • Drop capabilities & no new privileges — document running with --cap-drop=ALL (add back only what's needed), --security-opt=no-new-privileges, and a read-only root filesystem where possible.
  • HEALTHCHECK — add a HEALTHCHECK so orchestrators detect a broken container.
  • No unnecessary tooling — don't ship curl/wget/compilers/shells you don't need at runtime (distroless helps).

How to fix — before/after sketch

Before:

FROM python:latest
COPY . .
RUN pip install -r requirements.txt
CMD ["python", "app.py"]

After:

FROM python:3.12-slim@sha256:<digest> AS build
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt

FROM python:3.12-slim@sha256:<digest>
RUN useradd -m -u 10001 appuser
WORKDIR /app
COPY --from=build /install /usr/local
COPY --chown=appuser:appuser . .
USER appuser
HEALTHCHECK CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"
CMD ["python", "app.py"]

Pair with a .dockerignore (.git, .env, **/__pycache__, node_modules) and run at deploy time with --cap-drop=ALL --security-opt=no-new-privileges --read-only.

Report back

Give a short list of what was hardened (non-root, pinned digest, multi-stage, no secrets, .dockerignore, healthcheck, caps), the before/after Dockerfile, and the scan/lint commands to confirm. Flag anything that needs a runtime/orchestrator change (capabilities, read-only FS) the Dockerfile alone can't enforce.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.