Skip to content
Hidden Logic Lab

Block insecure Dockerfiles with an agent security SKILL.md

Claude Code or Cursor applies a SKILL.md to Dockerfile and Compose diffs: non-root users, secret leakage in layers, pinned bases, and healthchecks — with merge-blocking findings.

·Coding·30 min·Working

A docker-security skill in the repo, a PR comment listing severity-tagged findings, and fixes or explicit waivers before images ship to registry.

  1. 1

    Run one bad Dockerfile through the skill

    Use a deliberate test PR with a root user and a fake ARG secret. The skill should block before you trust it on real work.

  2. 2

    Align pins with CI

    Copy the same base-image policy your pipeline enforces. Agents will approve :latest if the skill does not name your registry rules.

  3. 3

    Wire Block to branch protection

    Optional: require the PR comment template for paths matching Dockerfile*. The skill is useless if reviewers merge on vibes.

The prompt to paste

Write SKILL.md for reviewing Dockerfile, docker-compose.yml, and related build scripts before merge. The agent produces merge-blocking findings, not generic security tips.

Repository context:
[paths to Dockerfiles, compose files, .dockerignore]
[base image policy: allowed registries, pin by digest or minor tag]
[runtime: Kubernetes, ECS, plain docker — affects healthcheck and signal handling]
[secret injection pattern: env at runtime, secrets mount, not build args for prod secrets]

Diff context (paste when using):
[PR diff or file paths changed]

SKILL.md must include:
1. Purpose — catch container misconfig before CI builds and pushes an image attackers can abuse.
2. When to use — any PR touching Dockerfile*, compose*, build workflows that docker build; when not to use — README-only.
3. Severity rubric the agent must use in findings:
   - Block: root USER 0, secrets in ENV/ARG/COPY layers, :latest-only base with no digest, missing .dockerignore exposing .git or .env, privileged: true or host mounts without justification.
   - Warn: no HEALTHCHECK when service is user-facing, running as root fallback, apt/apk upgrade in every build, shell as ENTRYPOINT for prod.
   - Note: style and layer caching — never block merge on style alone.
4. Required inputs: file list, intended environment (dev image vs prod image), and link to CI build job if any.
5. Review steps:
   - Read Dockerfile in build order; flag each RUN that embeds tokens, keys, or private URLs.
   - Confirm USER exists and is not root for prod-target images; if root required, demand comment with waiver id.
   - Check FROM pins: name registry, tag, and whether digest is required by policy.
   - Scan compose for secrets in environment: blocks, volume mounts of docker.sock, cap_add SYS_ADMIN.
   - Verify .dockerignore excludes .env*, **/credentials*, .git, and local build artifacts.
   - List findings as: [Block|Warn|Note] file:line — issue — suggested fix (one line).
6. PR comment template: Summary counts by severity, Findings table, Merge recommendation (block / approve with warns / approve).
7. Two example prompts: new Node service Dockerfile vs compose adding a sidecar.
8. Pitfalls: approving multi-stage builds that still COPY .env, confusing dev-only root with prod image, ignoring build-stage secrets that remain in layer history, waiving without ticket.
9. Done means: every Block resolved or waived with ticket, Warns acknowledged, no secret values reproduced in the comment.

Rules:
- Never echo real secret values from files; redact to [REDACTED].
- Do not invent CVEs; mention scanner output only if pasted.
- Output only SKILL.md markdown.

Build-time secrets live in layer history after you delete the line. The skill must treat ARG/ENV secrets as Block even if a later stage unsets them.

Sample case written by Hidden Logic Lab. Not affiliated with Cursor or Claude Code.

More in Coding

Get new cases in your inbox

Weekly notes on new use cases and agent workflows. No product pitches.

Occasional notes on new cases. No product pitches in the first note.