GitHub Packages · MIT · Node ≥ 18

dockerfile-sentinel

Security linter for Dockerfiles and Docker Compose files: root containers, baked-in secrets, curl | sh, unpinned and end-of-life base images, privileged services, Docker socket mounts and exposed databases.

Dockerfile and Docker Compose security linter: root users, unpinned or EOL base images, hardcoded secrets, curl | sh, disabled TLS/GPG checks, sensitive COPY, missing .dockerignore, privileged containers, docker.sock mounts, host namespaces and dangerous capabilities. Zero deps.

  1. 1 Point the @mrlouiswright scope at GitHub Packages in .npmrc

    @mrlouiswright:registry=https://npm.pkg.github.com
  2. 2 Install

    npm i -D @mrlouiswright/dockerfile-sentinel
Installing from GitHub Packages needs a token

Published to GitHub Packages, not npmjs.com. GitHub Packages needs a GitHub token with read:packages to install, even for public packages: add //npm.pkg.github.com/:_authToken=${GITHUB_TOKEN} to .npmrc or run npm login --registry=https://npm.pkg.github.com.

~/project — zsh
$ npx dockerfile-sentinel baddockerfile-sentinel — 2 target(s) bad/Dockerfile  kind: dockerfile  stages: 1  baseImages: node:16  CRITICAL bad/Dockerfile:6  AWS access key in ENV: AKI…LE (20 chars) [hardcoded-secret]           ↳ fix: Remove it, rotate the credential, and use BuildKit secrets (RUN --mount=type=secret) or runtime injection.  HIGH     bad/Dockerfile:13  COPY .env puts credentials/keys/.git into the image [copy-sensitive-file]           ↳ .env           ↳ fix: Mount it as a BuildKit secret or keep it out of the image.  HIGH     bad/Dockerfile:8  Downloads a script and pipes it straight into an interpreter [curl-pipe-shell]           ↳ fix: Download to a file, verify a checksum or signature, then run it.... 5 critical, 9 high, 9 medium, 4 low, 3 info✖ Failing (fail-on: high).
Real output from running dockerfile-sentinel locally on a test fixture.

Why it exists

dockerfile-sentinel reads Dockerfiles, Containerfiles and Compose files and reports security problems with a line number and a fix. CLI, library and GitHub Action. Node.js 18+, zero runtime dependencies. Nothing is built or pulled; files are only parsed. Secrets are masked in every output.

Features

Dockerfiles

final stage running as root, secrets in ENV/ARG/RUN (AWS, GitHub, Slack, Stripe, private keys and more), curl … | sh, disabled TLS verification, ADD of remote URLs without --checksum, HTTP downloads, chmod 777, base images that are end-of-life (Node, Python, Debian, Ubuntu, Alpine, CentOS…) or not pinned by digest, COPY . with no .dockerignore, copying .env/keys/.git into the image, SSH servers, sudo, apt-get upgrade, uncleaned package caches, missing HEALTHCHECK, deprecated MAINTAINER.

Compose

privileged, Docker/containerd socket mounts, host network/PID/IPC namespaces, dangerous capabilities (SYS_ADMIN, ALL…), seccomp/apparmor:unconfined, sensitive host paths (/, /etc, /proc…), literal secrets in environment, databases and admin APIs published on all interfaces, :latest/untagged images.

hardcoded-secret

Hardcoded credential or private key (default: critical)

secret-in-env

Secret-looking ENV value baked into the image (default: high)

secret-in-arg

Secret passed as a build ARG (visible in image history) (default: medium)

copy-sensitive-file

COPY/ADD of keys, .env, cloud credentials or .git (default: high)

missing-dockerignore

Build context copied without a .dockerignore (or it misses .git/.env) (default: medium)

run-as-root

Final stage runs as root (default: high)

Usage

# scan the current directory

 npx dockerfile-sentinel

# Example

 npx dockerfile-sentinel Dockerfile docker-compose.yml --fail-on medium

# Example

 npx dockerfile-sentinel services/ --format sarif > docker.sarif

CI / GitHub Action

permissions:
  contents: read
  security-events: write   # only for the SARIF upload
steps:
  - uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4
    with: { persist-credentials: false }
  - uses: MrLouisWright/dockerfile-sentinel@v1
    with:
      targets: '.'
      fail-on: high
      sarif: dockerfile-sentinel.sarif
  - uses: github/codeql-action/upload-sarif@v3
    if: always()
    with: { sarif_file: dockerfile-sentinel.sarif }

Options & flags

FlagDescription
--context <dir>Build context to look for .dockerignore (default: the Dockerfile's directory)
Policy and output
-c, --config <file>JSON config (default .dockerfile-sentinel.json if present)
-f, --format <fmt>text (default) | json | sarif | markdown
--json/--sarif/--markdown <file>Also write that format to a file
--fail-on <sev>critical | high | medium | low | info | none (default high)
--list-rulesPrint rules and default severities
--no-colorDisable colours

Full reference, config file format and API in the README.

Support this project

Support open-source security tools

I build free, open-source tools that help developers ship safer websites. Every coffee helps keep them maintained, documented and free for everyone.

Buy me a coffee (opens Stripe in a new tab)

Secure checkout by Stripe

Portrait of Louis Wright

About the author

Louis Wright

Cyber security researcher and software engineer based in the UK.

More tools by Louis Wright

58 tools

Sentinels security scanners & CI gates · 19