/hardening-dockerfiles
Hardening Dockerfiles to reach Docker Hub Health Score grade A: enforcing a non-root USER, minimal/distroless multi-stage base images, no fixable critical/high CVEs, no AGPL-3.0 deps, and SBOM+provenance attestations. Use when creating a new Dockerfile, auditing one for
$ npx -y skills add LerianStudio/ring --skill hardening-dockerfiles --agent claude-codeHow 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
/hardening-dockerfiles
Context preview
The summary Claude sees to decide when to auto-load this skill.
Hardening Dockerfiles to reach Docker Hub Health Score grade A: enforcing a non-root USER, minimal/distroless multi-stage base images, no fixable critical/high CVEs, no AGPL-3.0 deps, and SBOM+provenance attestations. Use when creating a new Dockerfile, auditing one for
SKILL.md
hardening-dockerfiles.SKILL.mdname: ring:hardening-dockerfiles
description: "Hardening Dockerfiles to reach Docker Hub Health Score grade A: enforcing a non-root USER, minimal/distroless multi-stage base images, no fixable critical/high CVEs, no AGPL-3.0 deps, and SBOM+provenance attestations. Use when creating a new Dockerfile, auditing one for security, or preparing images for Docker Hub publication. Skip when the project has no Dockerfile, changes are app-code-only, or you consume pre-built images."
Docker Security (Health Score Grade A)
When to use
- Creating a new Dockerfile
- Auditing an existing Dockerfile for security
- Preparing images for Docker Hub publication
- Docker Hub health score is below grade A
Skip when
- Project has no Dockerfile and none is being created
- Changes are application-code only with no Docker modifications
- Using pre-built images without custom Dockerfile
Related
**Complementary:** ring:implementing-tasks, ring:creating-helm-charts
General Dockerfile patterns: `dev-team/docs/standards/devops.md#containers`. This skill focuses on Docker Hub Health Score compliance.
Health Score Policies
| # | Policy | Weight | Compliance | |---|--------|--------|------------| | 1 | Default non-root user | Required | `USER` directive with non-root user | | 2 | No fixable critical/high CVEs | Required | Distroless or Alpine, multi-stage | | 3 | No high-profile vulnerabilities (CISA KEV) | Required | Up-to-date base images | | 4 | No AGPL v3 licenses | Required | Audit dependencies | | 5 | Supply chain attestations (SBOM + provenance) | Required | Pipeline config | | 6 | No outdated base images | Optional | Only for Docker Hub hosted images | | 7 | No unapproved base images | Optional | Only for Docker Hub hosted images |
Policies 6-7 are **not evaluated** when using non-Docker Hub base images (gcr.io/distroless, etc.).
Policy Implementation
Policy 1 — Non-Root User
# Alpine
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# Debian/Ubuntu
RUN groupadd -r appgroup && useradd -r -g appgroup appuser
USER appuser
# Distroless (pre-existing user)
USER nonroot:nonroot
`USER root` does NOT satisfy this policy.
Policies 2 & 3 — Minimal Attack Surface
# Go (statically compiled) — ~0 CVEs
FROM gcr.io/distroless/static-debian12
# Go (CGO) or general
FROM gcr.io/distroless/base-debian12
# Node.js
FROM node:22-alpine
# Multi-stage mandatory
FROM golang:1.23-alpine AS builder
# ... build ...
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/binary /app/binary
Policy 4 — No AGPL v3
trivy fs --scanners license --severity CRITICAL .
Replace any AGPL-3.0 dependency.
Policy 5 — Supply Chain Attestations (Pipeline)
# build-push-action config
sbom: generator=docker/scout-sbom-indexer:latest
provenance: mode=max
Not a Dockerfile concern — verify CI/CD includes both parameters.
Dockerfile Templates
Go Service
FROM golang:1.23-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ./cmd/...
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/app /app/app
EXPOSE 3000
USER nonroot:nonroot
ENTRYPOINT ["/app/app"]
TypeScript/Node.js
FROM node:22-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER appuser
CMD ["node", "dist/index.js"]
Audit Checklist
CRITICAL (blocks grade A):
[ ] USER directive with non-root user
[ ] Multi-stage build (no build tools in final)
[ ] Minimal base image (distroless/alpine)
[ ] No secrets in image layers
HIGH (CVE risk):
[ ] Base image is up to date
[ ] Package versions pinned
[ ] No dev dependencies in final stage
MEDIUM:
[ ] .dockerignore excludes .git, node_modules, test files
[ ] COPY used (not ADD)
[ ] Cache layers ordered: deps before source
SUPPLY CHAIN (pipeline):
[ ] sbom: parameter in build-push-action
[ ] provenance: mode=max
Report Template
## Health Score Compliance
| Policy | Status | Details |
|--------|--------|---------|
| Default non-root user | PASS/FAIL | USER {user} at line {N} |
| No fixable CVEs | PASS/RISK | Base: {image} |
| No KEV vulnerabilities | PASS/RISK | Base image {status} |
| No AGPL v3 licenses | PASS/RISK | {N} deps audited |
| Supply chain attestations | PASS/MISSING | sbom: {yes/no}, provenance: {yes/no} |
**Grade A: {ACHIEVED / NOT ACHIEVED}**
## Actions Taken
| File | Action | Changes |Read more
name: ring:hardening-dockerfiles description: "Hardening Dockerfiles to reach Docker Hub Health Score grade A: enforcing a non-root USER, minimal/distroless multi-stage base images, no fixable critical/high CVEs, no AGPL-3.0 deps, and SBOM+provenance attestations. Use when creating a new Dockerfile, auditing one for security, or preparing images for Docker Hub publication. Skip when the project has no Dockerfile, changes are app-code-only, or you consume pre-built images."
Docker Security (Health Score Grade A)
When to use
- Creating a new Dockerfile
- Auditing an existing Dockerfile for security
- Preparing images for Docker Hub publication
- Docker Hub health score is below grade A
Skip when
- Project has no Dockerfile and none is being created
- Changes are application-code only with no Docker modifications
- Using pre-built images without custom Dockerfile
Related
**Complementary:** ring:implementing-tasks, ring:creating-helm-charts
General Dockerfile patterns: `dev-team/docs/standards/devops.md#containers`. This skill focuses on Docker Hub Health Score compliance.
Health Score Policies
| # | Policy | Weight | Compliance | |---|--------|--------|------------| | 1 | Default non-root user | Required | `USER` directive with non-root user | | 2 | No fixable critical/high CVEs | Required | Distroless or Alpine, multi-stage | | 3 | No high-profile vulnerabilities (CISA KEV) | Required | Up-to-date base images | | 4 | No AGPL v3 licenses | Required | Audit dependencies | | 5 | Supply chain attestations (SBOM + provenance) | Required | Pipeline config | | 6 | No outdated base images | Optional | Only for Docker Hub hosted images | | 7 | No unapproved base images | Optional | Only for Docker Hub hosted images |
Policies 6-7 are **not evaluated** when using non-Docker Hub base images (gcr.io/distroless, etc.).
Policy Implementation
Policy 1 — Non-Root User
# Alpine RUN addgroup -S appgroup && adduser -S appuser -G appgroup USER appuser # Debian/Ubuntu RUN groupadd -r appgroup && useradd -r -g appgroup appuser USER appuser # Distroless (pre-existing user) USER nonroot:nonroot
`USER root` does NOT satisfy this policy.
Policies 2 & 3 — Minimal Attack Surface
# Go (statically compiled) — ~0 CVEs FROM gcr.io/distroless/static-debian12 # Go (CGO) or general FROM gcr.io/distroless/base-debian12 # Node.js FROM node:22-alpine # Multi-stage mandatory FROM golang:1.23-alpine AS builder # ... build ... FROM gcr.io/distroless/static-debian12 COPY --from=builder /app/binary /app/binary
Policy 4 — No AGPL v3
trivy fs --scanners license --severity CRITICAL .
Replace any AGPL-3.0 dependency.
Policy 5 — Supply Chain Attestations (Pipeline)
# build-push-action config sbom: generator=docker/scout-sbom-indexer:latest provenance: mode=max
Not a Dockerfile concern — verify CI/CD includes both parameters.
Dockerfile Templates
Go Service
FROM golang:1.23-alpine AS builder WORKDIR /app COPY go.mod go.sum ./ RUN go mod download COPY . . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app ./cmd/... FROM gcr.io/distroless/static-debian12 COPY --from=builder /app/app /app/app EXPOSE 3000 USER nonroot:nonroot ENTRYPOINT ["/app/app"]
TypeScript/Node.js
FROM node:22-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . RUN npm run build FROM node:22-alpine WORKDIR /app RUN addgroup -S appgroup && adduser -S appuser -G appgroup COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 USER appuser CMD ["node", "dist/index.js"]
Audit Checklist
CRITICAL (blocks grade A): [ ] USER directive with non-root user [ ] Multi-stage build (no build tools in final) [ ] Minimal base image (distroless/alpine) [ ] No secrets in image layers HIGH (CVE risk): [ ] Base image is up to date [ ] Package versions pinned [ ] No dev dependencies in final stage MEDIUM: [ ] .dockerignore excludes .git, node_modules, test files [ ] COPY used (not ADD) [ ] Cache layers ordered: deps before source SUPPLY CHAIN (pipeline): [ ] sbom: parameter in build-push-action [ ] provenance: mode=max
Report Template
## Health Score Compliance
| Policy | Status | Details |
|--------|--------|---------|
| Default non-root user | PASS/FAIL | USER {user} at line {N} |
| No fixable CVEs | PASS/RISK | Base: {image} |
| No KEV vulnerabilities | PASS/RISK | Base image {status} |
| No AGPL v3 licenses | PASS/RISK | {N} deps audited |
| Supply chain attestations | PASS/MISSING | sbom: {yes/no}, provenance: {yes/no} |
**Grade A: {ACHIEVED / NOT ACHIEVED}**
## Actions Taken
| File | Action | Changes |Proven engineering practices, enforced through skills. Ring is a comprehensive skills library and workflow system for AI agents that transforms how AI assistants approach software development.
Repo: LerianStudio/ring
Other skills on ring.
- /analyzing-options
Analyzing different approaches for a task or problem with structured comparisons, effort estimates, and recommendations. Use when facing strategic decisions, architecture choices, or multiple viable approaches. Skip when there's an obvious single approach or the decision is
Open skill - /auditing-production-readiness
Auditing a service's production readiness against Ring engineering standards across base dimensions plus a conditional multi-tenant dimension, then emitting a scored report and an HTML dashboard. Use before production deploy, periodic review, onboarding, or a major release. Skip
Open skill - /cleaning-comments
Cleaning redundant and obvious comments following clean code principles while preserving meaningful documentation. Supports git scope filtering (staged, unstaged, branch, commit-range). Use when code has excessive comments, during code review, or post-refactor cleanup. Skip when
Open skill - /committing-changes
Commit changes with scope allowlist enforcement, atomic grouping, GPG-signed conventional commits, and trailer management. Detects the repo's PR-validation scope policy before proposing any message. Use when the user asks to commit or has changes ready to record. Skip when the
Open skill - /creating-handoffs
Creating a handoff document that captures session state (completed work, decisions, open items, next steps) and delivering it via Plan Mode so the user gets the native 'clear context and continue implementing' resume option. Use when ending a session, when context grows large,
Open skill - /creating-worktrees
Creating an isolated git worktree for parallel branch work: selects the directory by priority order, verifies/adds .gitignore safety, auto-installs the detected toolchain's dependencies, runs a baseline test, and reports readiness. Use before a feature that needs isolation from
Open skill

