container-security-hardening — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited container-security-hardening (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A production-focused guide for building, scanning, and running containers securely — from Dockerfile authoring through runtime enforcement and supply chain integrity.
github-actions-advanceddocker-expertkubernetes-architectapi-security-best-practicesWhen invoked, first detect the current state:
# Find Dockerfiles in the project
find . -name "Dockerfile*" -not -path "*/node_modules/*" | head -10
# Check for existing security tooling
ls .trivyignore .hadolint.yaml .snyk docker-compose*.yml 2>/dev/null
# Inspect base images currently in use
grep -r "^FROM" $(find . -name "Dockerfile*") 2>/dev/null
# Check if Kubernetes manifests exist
find . -name "*.yaml" -path "*/k8s/*" -o -name "*.yaml" -path "*/manifests/*" | head -10Then adapt recommendations to:
1. Image Build → Minimal base, no secrets, non-root, read-only FS
2. Image Scanning → CVE scanning, SBOM, secret detection, Dockerfile lint
3. Runtime Security → Capabilities, seccomp, AppArmor, resource limits
4. Supply Chain → Signed images, pinned digests, trusted registries
5. Kubernetes Layer → Pod Security Admission, NetworkPolicy, RBAC, KyvernoWork through layers in order — hardening the image first gives the most leverage. See references/base-image-comparison.md for a full size/CVE trade-off table.# ❌ AVOID — massive attack surface (~100–200 CVEs typical)
FROM ubuntu:latest
FROM node:20
# ✅ BETTER — slim variants (glibc, smaller apt footprint)
FROM node:20-slim
FROM python:3.12-slim
# ✅ BEST — distroless (no shell, no package manager, built-in nonroot user)
FROM gcr.io/distroless/nodejs20-debian12
FROM gcr.io/distroless/python3-debian12
FROM gcr.io/distroless/static-debian12 # Go/Rust fully-static binaries
# ✅ ALSO GREAT — Alpine (musl libc; verify app compatibility first)
FROM alpine:3.20
# ✅ ZERO ATTACK SURFACE — for fully static binaries only
FROM scratchSee references/base-image-comparison.md for the full trade-off matrix.
Never ship build tools, compilers, or dev dependencies in a production image.
# syntax=docker/dockerfile:1
# ── Stage 1: Install & Build ──────────────────────────────
FROM node:20-slim AS builder
WORKDIR /build
COPY package*.json ./
RUN npm ci # Install all deps (including devDeps)
COPY . .
RUN npm run build && npm prune --production
# ── Stage 2: Runtime — minimal, no build tools ────────────
FROM gcr.io/distroless/nodejs20-debian12@sha256:<digest>
LABEL org.opencontainers.image.source="https://github.com/org/repo"
LABEL org.opencontainers.image.revision="${BUILD_SHA}"
LABEL org.opencontainers.image.licenses="MIT"
WORKDIR /app
COPY --from=builder --chown=nonroot:nonroot /build/dist ./dist
COPY --from=builder --chown=nonroot:nonroot /build/node_modules ./node_modules
USER nonroot:nonroot # UID 65532 — built into distroless
EXPOSE 3000
CMD ["dist/server.js"]Go / Rust static binary pattern:
FROM golang:1.22-alpine AS builder
WORKDIR /build
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o app .
FROM scratch # Zero attack surface
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY --from=builder /build/app /app
USER 65532:65532
ENTRYPOINT ["/app"]# For debian/ubuntu-based images — create dedicated user
RUN groupadd -r appgroup --gid 10001 && \
useradd~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.