
A fast, rule-based security scanner for Dockerfiles
Detect misconfigurations, exposed credentials, and security anti-patterns before they reach production.
Quick Start • Installation • GitHub Action • Usage • Rules • Custom Rules • Contributing
Dockerfiles can contain security issues that are easy to miss during code reviews:
USER directive leads to container privilege escalationlatest tag or images without SHA256 verificationARG instead of secretsCOPY . . accidentally including .env files and credentialsdockerfile-sec catches these issues automatically, integrating seamlessly into your development workflow and CI/CD pipelines.
| Feature | Description |
|---|---|
| 35 Built-in Rules | Comprehensive coverage of security best practices and credential detection |
| Blazing Fast | Written in Go for maximum performance on large codebases |
| Flexible Output | ASCII tables for humans, JSON for machines and automation |
| CI/CD Ready | Exit codes and quiet mode for seamless pipeline integration |
| Extensible | Load custom rules from local files or remote URLs |
| Zero Dependencies | Single static binary, no runtime required |
| Docker Support | Available as a minimal container image |
| Cross-Platform | Linux, macOS, and Windows support (amd64/arm64) |
# Download the binary (Linux/amd64)
curl -L https://github.com/cr0hn/dockerfile-security/releases/latest/download/dockerfile-sec-linux-amd64 -o dockerfile-sec
chmod +x dockerfile-sec
# Scan a Dockerfile
./dockerfile-sec Dockerfile
# Scan with exit code for CI/CD (exits 1 if issues found)
./dockerfile-sec -E Dockerfile
Example output:
+----------+-------------------------------------------+----------+
| Rule Id | Description | Severity |
+----------+-------------------------------------------+----------+
| core-002 | Posible text plain password in dockerfile | High |
| core-003 | Recursive copy found | Medium |
| core-005 | Use image tag instead of SHA256 hash | Medium |
| cred-001 | Generic credential | Medium |
+----------+-------------------------------------------+----------+
Download the latest release for your platform from the releases page.
| Platform | Architecture | Download |
|---|---|---|
| Linux | amd64 | dockerfile-sec-linux-amd64 |
| Linux | arm64 | dockerfile-sec-linux-arm64 |
| macOS | amd64 | dockerfile-sec-darwin-amd64 |
| macOS | arm64 (M1/M2) | dockerfile-sec-darwin-arm64 |
| Windows | amd64 | dockerfile-sec-windows-amd64.exe |
# Using GitHub Container Registry
docker pull ghcr.io/cr0hn/dockerfile-security:latest
# Scan a Dockerfile via stdin
cat Dockerfile | docker run --rm -i ghcr.io/cr0hn/dockerfile-security
# Scan a local file (mount as volume)
docker run --rm -v $(pwd):/app ghcr.io/cr0hn/dockerfile-security /app/Dockerfile
Requires Go 1.22 or later.
# Install directly
go install github.com/cr0hn/dockerfile-security/cmd/dockerfile-sec@latest
# Or build manually
git clone https://github.com/cr0hn/dockerfile-security.git
cd dockerfile-security
make build
You can use dockerfile-sec directly in your GitHub Actions workflows without manual installation.
name: Dockerfile Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan Dockerfile
uses: cr0hn/dockerfile-security@v0.2.0
with:
dockerfile: 'Dockerfile'
name: Advanced Dockerfile Security Scan
on: [push, pull_request]
jobs:
security-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan with custom settings
id: scan
uses: cr0hn/dockerfile-security@v0.2.0
with:
dockerfile: 'docker/Dockerfile.prod'
categories: 'core,credentials,security'
ignore-rules: 'core-001'
output-file: 'security-results.json'
fail-on-issues: true
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: security-scan-results
path: security-results.json
- name: Comment on PR
if: github.event_name == 'pull_request' && failure()
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
const results = JSON.parse(fs.readFileSync('security-results.json', 'utf8'));
const comment = `## 🔒 Dockerfile Security Scan Results\n\n` +
`Found ${results.length} security issues:\n\n` +
results.map(i => `- **${i.id}**: ${i.description} (${i.severity})`).join('\n');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: comment
});
| Input | Description | Required | Default |
|---|---|---|---|
dockerfile |
Path to Dockerfile to analyze | No | Dockerfile |
categories |
Rule categories (comma-separated): all, core, credentials, security, packages, configuration |
No | all |
ignore-rules |
Comma-separated rule IDs to ignore | No | '' |
ignore-file |
Path to ignore file | No | '' |
custom-rules |
Path to custom rules YAML file or URL | No | '' |
output-format |
Output format: table, json |
No | table |
output-file |
Path to save JSON output | No | '' |
fail-on-issues |
Exit with code 1 if issues found | No | true |
quiet |
Quiet mode (suppress output) | No | false |
version |
Version of dockerfile-sec to use | No | latest |
| Output | Description |
|---|---|
issues-found |
Number of security issues found |
exit-code |
Exit code of the scan (0=success, 1=issues) |
jobs:
scan-all:
runs-on: ubuntu-latest
strategy:
matrix:
dockerfile:
- Dockerfile
- docker/Dockerfile.dev
- docker/Dockerfile.prod
steps:
- uses: actions/checkout@v4
- name: Scan ${{ matrix.dockerfile }}
uses: cr0hn/dockerfile-security@v0.2.0
with:
dockerfile: ${{ matrix.dockerfile }}
- name: Credential Scan Only
uses: cr0hn/dockerfile-security@v0.2.0
with:
dockerfile: 'Dockerfile'
categories: 'credentials'
- name: Scan with Custom Rules
uses: cr0hn/dockerfile-security@v0.2.0
with:
dockerfile: 'Dockerfile'
custom-rules: '.github/dockerfile-rules.yaml'
# Scan a Dockerfile (outputs ASCII table in terminal, JSON when piped)
dockerfile-sec Dockerfile
# Read from stdin
cat Dockerfile | dockerfile-sec
# Quiet mode with exit code for scripts
if dockerfile-sec -E -q Dockerfile; then
echo "No security issues found"
else
echo "Security issues detected!"
exit 1
fi
The Docker image is available at ghcr.io/cr0hn/dockerfile-security.
Basic usage:
# Scan a Dockerfile via stdin
cat Dockerfile | docker run --rm -i ghcr.io/cr0hn/dockerfile-security
# Scan a local file (mount current directory)
docker run --rm -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security /workspace/Dockerfile
# Scan with exit code for CI/CD
docker run --rm -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security -E /workspace/Dockerfile
Advanced usage:
# Use a specific version
docker run --rm -i ghcr.io/cr0hn/dockerfile-security:v1.0.0
# With custom rules (mount rules file)
docker run --rm -i \
-v $(pwd)/Dockerfile:/Dockerfile \
-v $(pwd)/custom-rules.yaml:/rules.yaml \
ghcr.io/cr0hn/dockerfile-security -r /rules.yaml /Dockerfile
# Output JSON to a file
docker run --rm -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security \
-o /workspace/results.json /workspace/Dockerfile
# Ignore specific rules
docker run --rm -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security \
-i core-001 -i core-004 /workspace/Dockerfile
# Only credential rules
docker run --rm -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security \
-R credentials /workspace/Dockerfile
Docker Compose integration:
# docker-compose.yml
services:
dockerfile-sec:
image: ghcr.io/cr0hn/dockerfile-security:latest
volumes:
- ./Dockerfile:/Dockerfile:ro
command: ["-E", "/Dockerfile"]
Shell alias for convenience:
# Add to ~/.bashrc or ~/.zshrc
alias dockerfile-sec='docker run --rm -i -v $(pwd):/workspace ghcr.io/cr0hn/dockerfile-security'
# Usage
dockerfile-sec /workspace/Dockerfile
dockerfile-sec -E /workspace/Dockerfile
dockerfile-sec works seamlessly in UNIX pipelines:
# Chain with jq for JSON processing
cat Dockerfile | dockerfile-sec | jq '.[] | select(.severity == "High")'
# Process multiple Dockerfiles
find . -name "Dockerfile*" -exec dockerfile-sec -E {} \;
name: Security Scan
on: [push, pull_request]
jobs:
dockerfile-security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Scan Dockerfile
run: |
curl -sL https://github.com/cr0hn/dockerfile-security/releases/latest/download/dockerfile-sec-linux-amd64 -o dockerfile-sec
chmod +x dockerfile-sec
./dockerfile-sec -E Dockerfile
dockerfile-security:
image: ghcr.io/cr0hn/dockerfile-security:latest
script:
- dockerfile-sec -E Dockerfile
rules:
- changes:
- Dockerfile
- "*.dockerfile"
```groo
$ claude mcp add dockerfile-security \
-- python -m otcore.mcp_server <graph>