Initial commit
This commit is contained in:
9
skills/devsecops/container-hadolint/assets/.gitkeep
Normal file
9
skills/devsecops/container-hadolint/assets/.gitkeep
Normal file
@@ -0,0 +1,9 @@
|
||||
# Assets Directory
|
||||
|
||||
Place files that will be used in the output Claude produces:
|
||||
- Templates
|
||||
- Configuration files
|
||||
- Images/logos
|
||||
- Boilerplate code
|
||||
|
||||
These files are NOT loaded into context but copied/modified in output.
|
||||
@@ -0,0 +1,99 @@
|
||||
# GitHub Actions workflow for Hadolint Dockerfile linting
|
||||
# Place this file at: .github/workflows/hadolint.yml
|
||||
|
||||
name: Hadolint Dockerfile Security Scan
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
paths:
|
||||
- '**/Dockerfile*'
|
||||
- '**/*.dockerfile'
|
||||
- '.github/workflows/hadolint.yml'
|
||||
pull_request:
|
||||
branches: [ main, develop ]
|
||||
paths:
|
||||
- '**/Dockerfile*'
|
||||
- '**/*.dockerfile'
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
security-events: write # For SARIF upload
|
||||
pull-requests: write # For PR comments
|
||||
|
||||
jobs:
|
||||
hadolint:
|
||||
name: Lint Dockerfiles
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Run Hadolint
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: "Dockerfile" # Change to your Dockerfile path
|
||||
failure-threshold: warning
|
||||
format: sarif
|
||||
output-file: hadolint-results.sarif
|
||||
config: .hadolint.yaml # Optional: use custom config
|
||||
|
||||
- name: Upload SARIF to GitHub Security
|
||||
if: always()
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: hadolint-results.sarif
|
||||
category: hadolint
|
||||
|
||||
- name: Generate readable report
|
||||
if: failure()
|
||||
uses: hadolint/hadolint-action@v3.1.0
|
||||
with:
|
||||
dockerfile: "Dockerfile"
|
||||
format: tty
|
||||
|
||||
hadolint-all:
|
||||
name: Lint All Dockerfiles
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Find all Dockerfiles
|
||||
id: find-dockerfiles
|
||||
run: |
|
||||
# Find all Dockerfile* in repository
|
||||
DOCKERFILES=$(find . -type f \( -name "Dockerfile*" -o -name "*.dockerfile" \) | tr '\n' ' ')
|
||||
echo "dockerfiles=$DOCKERFILES" >> $GITHUB_OUTPUT
|
||||
echo "Found Dockerfiles: $DOCKERFILES"
|
||||
|
||||
- name: Run Hadolint on all Dockerfiles
|
||||
run: |
|
||||
# Install hadolint
|
||||
wget -O /usr/local/bin/hadolint https://github.com/hadolint/hadolint/releases/latest/download/hadolint-Linux-x86_64
|
||||
chmod +x /usr/local/bin/hadolint
|
||||
|
||||
# Scan each Dockerfile
|
||||
FAILED=0
|
||||
for dockerfile in ${{ steps.find-dockerfiles.outputs.dockerfiles }}; do
|
||||
echo "Scanning: $dockerfile"
|
||||
if ! hadolint --failure-threshold warning "$dockerfile"; then
|
||||
FAILED=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $FAILED
|
||||
|
||||
- name: Comment PR with results
|
||||
if: github.event_name == 'pull_request' && failure()
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: '❌ Hadolint found security issues in Dockerfiles. Please review the workflow logs and fix the issues.'
|
||||
})
|
||||
82
skills/devsecops/container-hadolint/assets/gitlab-ci.yml
Normal file
82
skills/devsecops/container-hadolint/assets/gitlab-ci.yml
Normal file
@@ -0,0 +1,82 @@
|
||||
# GitLab CI configuration for Hadolint Dockerfile linting
|
||||
# Add this to your .gitlab-ci.yml file
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- build
|
||||
|
||||
# Hadolint Dockerfile security scanning
|
||||
hadolint:
|
||||
stage: lint
|
||||
image: hadolint/hadolint:latest-debian
|
||||
script:
|
||||
# Find all Dockerfiles
|
||||
- |
|
||||
DOCKERFILES=$(find . -type f \( -name "Dockerfile*" -o -name "*.dockerfile" \))
|
||||
echo "Found Dockerfiles:"
|
||||
echo "$DOCKERFILES"
|
||||
|
||||
# Scan each Dockerfile and generate reports
|
||||
- |
|
||||
FAILED=0
|
||||
for dockerfile in $DOCKERFILES; do
|
||||
echo "Scanning: $dockerfile"
|
||||
|
||||
# Generate GitLab Code Quality report
|
||||
hadolint -f gitlab_codeclimate "$dockerfile" >> hadolint-report.json || FAILED=1
|
||||
|
||||
# Also print human-readable output
|
||||
hadolint "$dockerfile" || true
|
||||
done
|
||||
|
||||
exit $FAILED
|
||||
|
||||
artifacts:
|
||||
reports:
|
||||
codequality: hadolint-report.json
|
||||
paths:
|
||||
- hadolint-report.json
|
||||
when: always
|
||||
expire_in: 1 week
|
||||
|
||||
# Only run on branches with Dockerfile changes
|
||||
rules:
|
||||
- changes:
|
||||
- "**/Dockerfile*"
|
||||
- "**/*.dockerfile"
|
||||
- ".gitlab-ci.yml"
|
||||
|
||||
# Alternative: Scan specific Dockerfile
|
||||
hadolint-main:
|
||||
stage: lint
|
||||
image: hadolint/hadolint:latest-debian
|
||||
script:
|
||||
- hadolint --failure-threshold warning Dockerfile
|
||||
only:
|
||||
changes:
|
||||
- Dockerfile
|
||||
|
||||
# Advanced: Multiple Dockerfiles with matrix
|
||||
hadolint-matrix:
|
||||
stage: lint
|
||||
image: hadolint/hadolint:latest-debian
|
||||
parallel:
|
||||
matrix:
|
||||
- DOCKERFILE:
|
||||
- "Dockerfile"
|
||||
- "Dockerfile.dev"
|
||||
- "services/api/Dockerfile"
|
||||
- "services/web/Dockerfile"
|
||||
script:
|
||||
- |
|
||||
if [ -f "$DOCKERFILE" ]; then
|
||||
echo "Scanning: $DOCKERFILE"
|
||||
hadolint --failure-threshold warning "$DOCKERFILE"
|
||||
else
|
||||
echo "File not found: $DOCKERFILE"
|
||||
exit 1
|
||||
fi
|
||||
only:
|
||||
changes:
|
||||
- Dockerfile*
|
||||
- services/**/Dockerfile*
|
||||
@@ -0,0 +1,40 @@
|
||||
# Hadolint Balanced Configuration
|
||||
# Recommended for most production use cases
|
||||
# Balances security enforcement with practical development needs
|
||||
|
||||
failure-threshold: warning
|
||||
|
||||
# Allow common development patterns that don't compromise security
|
||||
ignored:
|
||||
- DL3059 # Multiple RUN instructions (improves layer caching in development)
|
||||
|
||||
# Trusted registries - add your organization's registries
|
||||
trustedRegistries:
|
||||
- docker.io/library # Official Docker Hub images
|
||||
- gcr.io/distroless # Google distroless images
|
||||
- cgr.dev/chainguard # Chainguard images
|
||||
# Add your private registries below:
|
||||
# - mycompany.azurecr.io
|
||||
# - gcr.io/my-project
|
||||
|
||||
# Balanced severity levels
|
||||
override:
|
||||
error:
|
||||
- DL3002 # Never switch to root (critical security)
|
||||
- DL3020 # Use COPY instead of ADD (prevent URL injection)
|
||||
warning:
|
||||
- DL3000 # Use absolute WORKDIR
|
||||
- DL3001 # Version pinning for package managers
|
||||
- DL3006 # Always tag images
|
||||
- DL3008 # Version pinning for apt
|
||||
- DL3013 # Version pinning for pip
|
||||
- DL3025 # Use JSON notation for CMD/ENTRYPOINT
|
||||
info:
|
||||
- DL3007 # Use image digests (nice to have)
|
||||
- DL3009 # Delete apt cache (optimization)
|
||||
|
||||
# Recommended OCI labels
|
||||
label-schema:
|
||||
maintainer: text
|
||||
org.opencontainers.image.version: semver
|
||||
org.opencontainers.image.vendor: text
|
||||
@@ -0,0 +1,35 @@
|
||||
# Hadolint Permissive Configuration
|
||||
# For legacy Dockerfiles during migration or development environments
|
||||
# Use temporarily while remediating existing issues
|
||||
|
||||
failure-threshold: error # Only fail on critical security issues
|
||||
|
||||
# Ignore common legacy patterns (review and remove as you fix them)
|
||||
ignored:
|
||||
- DL3006 # Image versioning (fix gradually)
|
||||
- DL3008 # apt-get version pinning (fix gradually)
|
||||
- DL3009 # apt cache cleanup (optimization, not security)
|
||||
- DL3013 # pip version pinning (fix gradually)
|
||||
- DL3015 # apt --no-install-recommends (optimization)
|
||||
- DL3059 # Multiple RUN instructions (caching)
|
||||
|
||||
# Still enforce trusted registries
|
||||
trustedRegistries:
|
||||
- docker.io
|
||||
- gcr.io
|
||||
- ghcr.io
|
||||
# Add your registries
|
||||
|
||||
# Minimal enforcement - only critical security issues
|
||||
override:
|
||||
error:
|
||||
- DL3002 # Never switch to root (always enforce)
|
||||
- DL3020 # Use COPY instead of ADD (security critical)
|
||||
warning:
|
||||
- DL3001 # Package manager version pinning
|
||||
- DL3025 # JSON notation for CMD/ENTRYPOINT
|
||||
info:
|
||||
# Everything else is informational
|
||||
- DL3000
|
||||
- DL3003
|
||||
- DL3007
|
||||
@@ -0,0 +1,48 @@
|
||||
# Hadolint Strict Configuration
|
||||
# Enforces maximum security with minimal exceptions
|
||||
# Use for: Production Dockerfiles, security-critical applications
|
||||
|
||||
failure-threshold: error
|
||||
|
||||
# Minimal ignores - only critical exceptions
|
||||
ignored: []
|
||||
|
||||
# Only trust official and verified registries
|
||||
trustedRegistries:
|
||||
- docker.io/library # Official Docker Hub images
|
||||
- gcr.io/distroless # Google distroless base images
|
||||
- cgr.dev/chainguard # Chainguard minimal images
|
||||
|
||||
# Enforce strict severity levels
|
||||
override:
|
||||
error:
|
||||
- DL3000 # Use absolute WORKDIR
|
||||
- DL3001 # Version pinning for yum
|
||||
- DL3002 # Never switch to root
|
||||
- DL3003 # Use WORKDIR instead of cd
|
||||
- DL3006 # Always tag images
|
||||
- DL3008 # Version pinning for apt
|
||||
- DL3013 # Version pinning for pip
|
||||
- DL3016 # Version pinning for npm
|
||||
- DL3018 # Version pinning for apk
|
||||
- DL3020 # Use COPY instead of ADD
|
||||
- DL3028 # Use build secrets for credentials
|
||||
warning:
|
||||
- DL3007 # Use specific digests (recommended)
|
||||
- DL3009 # Delete apt cache
|
||||
- DL3015 # Avoid additional packages
|
||||
- DL3025 # Use JSON notation
|
||||
|
||||
# Enforce OCI image labels
|
||||
label-schema:
|
||||
maintainer: text
|
||||
org.opencontainers.image.created: rfc3339
|
||||
org.opencontainers.image.authors: text
|
||||
org.opencontainers.image.url: url
|
||||
org.opencontainers.image.documentation: url
|
||||
org.opencontainers.image.source: url
|
||||
org.opencontainers.image.version: semver
|
||||
org.opencontainers.image.revision: text
|
||||
org.opencontainers.image.vendor: text
|
||||
org.opencontainers.image.title: text
|
||||
org.opencontainers.image.description: text
|
||||
Reference in New Issue
Block a user