Files
wehub-resource-sync 7a0da7932b
Backwards Compatibility / Verify Encryption Constants (push) Waiting to run
Backwards Compatibility / PyPI Version Compatibility (push) Waiting to run
Backwards Compatibility / Database Migration Tests (push) Waiting to run
CodeQL Advanced / Analyze (javascript-typescript) (push) Waiting to run
CodeQL Advanced / Analyze (python) (push) Waiting to run
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Blocked by required conditions
Docker Tests (Consolidated) / detect-changes (push) Waiting to run
Docker Tests (Consolidated) / Build Test Image (push) Waiting to run
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Blocked by required conditions
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Blocked by required conditions
Docker Tests (Consolidated) / Accessibility Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Unit Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / LLM Example Tests (push) Blocked by required conditions
Docker Tests (Consolidated) / Production Image Smoke Test (push) Blocked by required conditions
Docker Tests (Consolidated) / Infrastructure Tests (push) Blocked by required conditions
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Waiting to run
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:08:55 +08:00

212 lines
9.1 KiB
YAML

name: Dockle Container Security Linting
on:
workflow_dispatch:
workflow_call: # Called by release-gate.yml
schedule:
# Run weekly on Tuesday at 10 AM UTC (staggered with other container scans)
- cron: '0 10 * * 2'
permissions: {} # Minimal top-level for OSSF Scorecard Token-Permissions
jobs:
dockle:
name: Dockle Container Image Security
runs-on: ubuntu-latest
timeout-minutes: 30
permissions:
contents: read
security-events: write
steps:
- name: Harden the runner (Audit all outbound calls)
uses: step-security/harden-runner@9af89fc71515a100421586dfdb3dc9c984fbf411 # v2.19.4
with:
egress-policy: audit
- name: Checkout repository
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with:
persist-credentials: false
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
- name: Build Docker image for scanning
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
with:
context: .
push: false
load: true
tags: local-deep-research:dockle-scan
cache-from: type=gha,scope=dockle-scan
cache-to: type=gha,mode=max,scope=dockle-scan
- name: Run Dockle security scan
id: dockle
run: |
echo "=== Running Dockle Container Image Security Scan ==="
# Run Dockle with SARIF output for GitHub Security tab
# Mount current directory to /output so SARIF file is written to host filesystem
# Exit code 1 means issues found, but we don't fail the workflow
#
# Ignored checks (false positives or intentional design):
# - CIS-DI-0001: Create a user - image uses setpriv entrypoint pattern for privilege drop
# (see scripts/ldr_entrypoint.sh which uses setpriv to switch to ldruser)
# - CIS-DI-0005: Enable Content trust for Docker - runtime env var (DOCKER_CONTENT_TRUST),
# not a Dockerfile concern; enforced at deployment time
# - CIS-DI-0008: setuid/setgid files - unix_chkpwd is standard Debian base utility
# required for PAM authentication, inherited from python:3.14-slim base image
# - DKL-DI-0005: Clear apt-get caches - already done in Dockerfile (rm -rf /var/lib/apt/lists/*),
# but base image (python:3.14-slim) layers trigger this check
#
# Accepted files (false positives):
# - unix_chkpwd: PAM utility from Debian base image
# - settings.py: Any file named settings.py (config files, not credentials)
# Without --exit-code flag, Dockle always exits 0 regardless of findings.
# Findings are reported via SARIF and enforced by the release gate
# (check-code-scanning-alerts job in release-gate.yml).
# Any non-zero exit code here means Docker itself failed (image pull error,
# socket unavailable, etc.) — a broken scanner that MUST fail the step,
# otherwise no SARIF is produced and the release gate has nothing to check.
set +e
docker run --rm \
-v /var/run/docker.sock:/var/run/docker.sock \
-v "$(pwd):/output" \
goodwithtech/dockle:v0.4.14 \
--format sarif \
--output /output/dockle-results.sarif \
--ignore CIS-DI-0001 \
--ignore CIS-DI-0005 \
--ignore CIS-DI-0008 \
--ignore DKL-DI-0005 \
--accept-file "usr/sbin/unix_chkpwd" \
--accept-file "settings.py" \
local-deep-research:dockle-scan
DOCKLE_EXIT_CODE=$?
set -e
if [ "$DOCKLE_EXIT_CODE" -ne 0 ]; then
echo "::error::Dockle/Docker failed with exit code $DOCKLE_EXIT_CODE"
exit 1
fi
# Check if SARIF file was created (for use in subsequent steps)
if [ -f "dockle-results.sarif" ]; then
echo "sarif_exists=true" >> "$GITHUB_OUTPUT"
# Check if SARIF contains any findings (used by summary step)
RESULT_COUNT=$(python3 -c "import json; print(len(json.load(open('dockle-results.sarif')).get('runs',[{}])[0].get('results',[])))" 2>/dev/null || echo "0")
if [ "$RESULT_COUNT" -gt 0 ]; then
echo "DOCKLE_FOUND_ISSUES=true" >> "$GITHUB_ENV"
fi
fi
- name: Run Dockle with human-readable output
if: always()
run: |
echo "=== Dockle Scan Results ==="
# Use same ignore flags as SARIF scan for consistent output
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
goodwithtech/dockle:v0.4.14 \
--format list \
--ignore CIS-DI-0001 \
--ignore CIS-DI-0005 \
--ignore CIS-DI-0008 \
--ignore DKL-DI-0005 \
--accept-file "usr/sbin/unix_chkpwd" \
--accept-file "settings.py" \
local-deep-research:dockle-scan || true
- name: Upload Dockle results to GitHub Security tab
uses: github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # v4.36.3
# Note: hashFiles() is evaluated at workflow parse time, not runtime.
# Use step output instead to check if SARIF file was created during the run.
if: always() && steps.dockle.outputs.sarif_exists == 'true'
with:
sarif_file: dockle-results.sarif
category: dockle
- name: Upload Dockle results as artifact
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
if: always() && steps.dockle.outputs.sarif_exists == 'true'
with:
name: dockle-results
path: dockle-results.sarif
retention-days: 7 # Reduced for security
- name: Display Dockle summary
if: always()
run: |
{
echo "## 🐋 Dockle Container Image Security Summary"
echo ""
echo "### What is Dockle?"
echo "Dockle is a container image linting tool that checks for:"
echo ""
echo "#### 🎯 Security Checks:"
echo "- **Sensitive Files**: Keys, certificates, passwords in image"
echo "- **Root User**: Warning if running as root"
echo "- **Clear-text Passwords**: Detects plaintext secrets"
echo "- **CIS Benchmarks**: Container security best practices"
echo "- **Outdated Packages**: Vulnerable base images"
echo ""
echo "#### 📊 Dockle vs Hadolint:"
echo "- **Hadolint**: Checks Dockerfile source code (best practices)"
echo "- **Dockle**: Scans built container image (runtime security)"
echo "- **Both Complement**: Check different stages of container lifecycle"
echo ""
echo "#### 🔍 Scan Results:"
} >> "$GITHUB_STEP_SUMMARY"
if [ "$DOCKLE_FOUND_ISSUES" = "true" ]; then
{
echo "⚠️ **Issues Found**"
echo ""
echo "Dockle detected security or best practice issues:"
echo ""
echo "**Common Issues:**"
echo "- Running as root user (consider USER directive)"
echo "- Sensitive files potentially included in image"
echo "- Missing security labels or metadata"
echo "- Outdated base image packages"
echo ""
echo "📋 **Detailed Results:**"
echo "- GitHub Security tab: SARIF results uploaded"
echo "- Artifacts: Full SARIF report available"
echo "- Check output above for human-readable format"
} >> "$GITHUB_STEP_SUMMARY"
else
{
echo "✅ **No Issues Found!**"
echo ""
echo "Container image passed all Dockle security checks."
} >> "$GITHUB_STEP_SUMMARY"
fi
{
echo ""
echo "#### 🔗 Resources:"
echo "- [Dockle GitHub](https://github.com/goodwithtech/dockle)"
echo "- [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker)"
echo "- [Security Tab](https://github.com/${{ github.repository }}/security/code-scanning)"
echo ""
echo "#### 💡 Best Practices:"
echo "- Use multi-stage builds to reduce image size"
echo "- Add USER directive to run as non-root"
echo "- Don't include secrets or keys in image"
echo "- Keep base images updated"
echo "- Scan images with both Dockle (runtime) and Hadolint (build)"
echo ""
echo "#### 🔇 Ignored Checks (false positives or intentional design):"
echo "- **CIS-DI-0001** (Create a user): Uses setpriv entrypoint pattern for privilege drop"
echo "- **CIS-DI-0005** (Content trust): Runtime env var, not Dockerfile concern"
echo "- **CIS-DI-0008** (setuid/setgid): unix_chkpwd from Debian base, required for PAM"
echo "- **DKL-DI-0005** (apt-get cache): Dockerfile clears caches, base image triggers this"
echo "- **settings.py**: Any file named settings.py accepted (config files, not credentials)"
} >> "$GITHUB_STEP_SUMMARY"
- name: Clean up Docker image
if: always()
run: |
docker rmi local-deep-research:dockle-scan || true