From d70cfc07bb45ea8d3daa4d9656efebc4606dd72e Mon Sep 17 00:00:00 2001 From: Konstantin Renner Date: Wed, 25 Mar 2026 16:59:08 +0100 Subject: [PATCH] feat: Dynamically discover Docker images from repo for security scanning --- .woodpecker/security-scan.yml | 50 +++++++++++++---------------------- 1 file changed, 18 insertions(+), 32 deletions(-) diff --git a/.woodpecker/security-scan.yml b/.woodpecker/security-scan.yml index 49129e66..2c6e1c0a 100644 --- a/.woodpecker/security-scan.yml +++ b/.woodpecker/security-scan.yml @@ -19,36 +19,22 @@ steps: image: aquasec/trivy:latest commands: - trivy image --download-db-only - # Databases - - echo "=== postgres:15 ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/library/postgres:15 || true - - echo "=== postgres:16 ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/library/postgres:16 || true - - echo "=== redis:7 ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/library/redis:7 || true - - echo "=== redis:6.2-alpine ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/library/redis:6.2-alpine || true - - echo "=== pgvecto-rs ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed tensorchord/pgvecto-rs:pg16-v0.2.1 || true - # Paperless - - echo "=== paperless-ngx ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/paperless-ngx/paperless-ngx:latest || true - - echo "=== paperless-gpt ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/icereed/paperless-gpt:latest || true - - echo "=== gotenberg:8 ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/gotenberg/gotenberg:8 || true - - echo "=== tika ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.io/apache/tika:latest || true - # Authentik - - echo "=== authentik ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/goauthentik/server:latest || true - # Immich - - echo "=== immich-server ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/immich-app/immich-server:release || true - - echo "=== immich-ml ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/immich-app/immich-machine-learning:release || true - # Woodpecker - - echo "=== woodpecker-server ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed woodpeckerci/woodpecker-server:v3.13.0 || true - - echo "=== woodpecker-agent ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed woodpeckerci/woodpecker-agent:v3.13.0 || true - # NetBird - - echo "=== netbird-management ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed netbirdio/management:latest || true - - echo "=== netbird-signal ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed netbirdio/signal:latest || true - - echo "=== netbird-dashboard ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed netbirdio/dashboard:latest || true - - echo "=== netbird-relay ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed netbirdio/relay:latest || true - # Other services - - echo "=== n8n ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed docker.n8n.io/n8nio/n8n:2.11.0 || true - - echo "=== grist ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed gristlabs/grist:latest || true - - echo "=== music-assistant ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed ghcr.io/music-assistant/server:latest || true - - echo "=== coturn ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed coturn/coturn:latest || true - - echo "=== syncthing ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed syncthing/syncthing:latest || true - - echo "=== traefik ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed traefik:latest || true - - echo "=== protonmail-bridge ===" && trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed shenxn/protonmail-bridge || true + - | + # Extract all Docker images from ansible configs and docker-compose templates + grep -rh 'image:' ansible/ --include='*.yml' --include='*.yaml' --include='*.j2' \ + | sed 's/.*image:\s*//' | tr -d '"' | tr -d "'" \ + | sed 's/\${[^}]*:-\([^}]*\)}/\1/g' \ + | sed 's/\${[^}]*}//g' \ + | sed 's/{{ *[a-z_]* *}}/latest/g' \ + | grep -v '^$' | grep -v 'cmd:' | grep -v '{' \ + | sort -u > /tmp/images.txt + echo "Found images to scan:" + cat /tmp/images.txt + echo "---" + FAILED=0 + while IFS= read -r img; do + echo "=== $img ===" + trivy image --skip-db-update --severity CRITICAL,HIGH --ignore-unfixed "$img" || FAILED=$((FAILED+1)) + done < /tmp/images.txt + echo "=== Scan complete: $FAILED image(s) with findings ===" failure: ignore