From 340a0fb604efe638b57bcac156da9c3597cccd8c Mon Sep 17 00:00:00 2001 From: Vipin Yadav Date: Mon, 23 Mar 2026 10:50:27 +0530 Subject: [PATCH] wiz cli CHEF-32378 Signed-off-by: Vipin Yadav --- .github/workflows/ci-main-pull-request.yml | 18 +++ .github/workflows/wiz.yml | 173 +++++++++++++++++++++ 2 files changed, 191 insertions(+) create mode 100644 .github/workflows/wiz.yml diff --git a/.github/workflows/ci-main-pull-request.yml b/.github/workflows/ci-main-pull-request.yml index d677565..5bd1046 100644 --- a/.github/workflows/ci-main-pull-request.yml +++ b/.github/workflows/ci-main-pull-request.yml @@ -541,6 +541,16 @@ on: # required: false # default: 'https://polaris.blackduck.com' # type: string + perform-wiz-scan: + description: 'Perform Wiz CLI security scan on Docker image' + required: false + type: boolean + default: false + wiz-fail-build: + description: 'Fail the build on Wiz policy violations' + required: false + type: boolean + default: true env: PRIMARY_APPLICATION: ${{ inputs.application }} # was 'default' # Custom repo property [primaryApplication]: chef360, automate, infra-server, habitat, supermarket, licensing, downloads, chef-client, inspec, chef-workstation (or derivatives like habitat-builder) @@ -1129,6 +1139,14 @@ jobs: # echo "VERSION=$VER" >> $GITHUB_ENV # then ${{ env.VERSION }} + run-wiz-scan: + name: 'Wiz CLI security scan' + if: ${{ inputs.perform-wiz-scan == true }} + uses: chef/common-github-actions/.github/workflows/wiz.yml@main + with: + fail-build: ${{ inputs.wiz-fail-build }} + secrets: inherit + set-application-version: runs-on: ubuntu-latest name: 'Detect SBOM version for application' diff --git a/.github/workflows/wiz.yml b/.github/workflows/wiz.yml new file mode 100644 index 0000000..0e9cad3 --- /dev/null +++ b/.github/workflows/wiz.yml @@ -0,0 +1,173 @@ +# wiz.yml +# Wiz CLI security scan for Docker image vulnerabilities and policy violations +# Uses the prgs-community/githubactions-reusableworkflows/actions/wizcli composite action +# which handles Wiz CLI install, AKeyless auth, scanning, and job summary automatically. +# https://docs.wiz.io/wiz-docs/docs/wiz-cli-overview + +name: Wiz CLI security scan + +on: + workflow_call: + inputs: + fail-build: + description: 'Fail the build on Wiz policy violations' + required: false + type: boolean + default: true + +jobs: + wiz-scan: + name: Wiz CLI container image scan + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + steps: + - name: Checkout code + uses: actions/checkout@v6 + with: + fetch-depth: 0 + + - name: Configure git for private repos + run: git config --global url."https://${{ secrets.GH_TOKEN }}@github.com/".insteadOf "https://github.com/" + + - name: Build Docker image + id: build-image + env: + GITHUB_TOKEN: ${{ secrets.GH_TOKEN }} + run: | + REPO_NAME=$(basename $(pwd)) + + if [ ! -f "Dockerfile" ]; then + echo "❌ No Dockerfile found - this workflow requires a Dockerfile to scan Docker image" + exit 1 + fi + + echo "Building Docker image..." + + # Strategy 1: Check for build-docker.sh script (e.g., dsm-erchef) + if [ -f "build-docker.sh" ]; then + echo "Found build-docker.sh script - using it to build images" + chmod +x build-docker.sh + GITHUB_TOKEN="${{ secrets.GH_TOKEN }}" ./build-docker.sh + + IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -E "^${REPO_NAME}" | grep -v "^" | head -1) + + if [ -z "$IMAGE" ]; then + echo "⚠️ No image found with prefix ${REPO_NAME} after build-docker.sh" + echo "Checking for any recently built images..." + IMAGE=$(docker images --format "{{.CreatedAt}}\t{{.Repository}}:{{.Tag}}" | sort -r | head -1 | cut -f2) + fi + # Strategy 2: Check for Makefile with compose-build target + elif [ -f "Makefile" ] && grep -q "^compose-build:" Makefile; then + echo "Using Makefile compose-build target with GITHUB_TOKEN" + export GITHUB_TOKEN="${{ secrets.GH_TOKEN }}" + + # Record image IDs before build to detect newly built images + BEFORE_IDS=$(docker images -q --no-trunc | sort) + + make compose-build + + echo "Detecting built image..." + # Find newly created images by comparing before/after image IDs + AFTER_IDS=$(docker images -q --no-trunc | sort) + NEW_IDS=$(comm -13 <(echo "$BEFORE_IDS") <(echo "$AFTER_IDS")) + + if [ -n "$NEW_IDS" ]; then + for id in $NEW_IDS; do + IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" --filter "id=${id}" | grep -v "" | head -1) + [ -n "$IMAGE" ] && break + done + fi + + if [ -z "$IMAGE" ]; then + echo "No new image detected, using most recent image" + IMAGE=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "^" | head -1) + fi + # Strategy 3: Fallback to standard docker build + else + echo "Using standard docker build with GITHUB_TOKEN build arg" + docker build --build-arg GITHUB_TOKEN="${{ secrets.GH_TOKEN }}" -t "${REPO_NAME}:latest" . + IMAGE="${REPO_NAME}:latest" + fi + + if [ -z "$IMAGE" ]; then + echo "❌ No Docker image found after build" + exit 1 + fi + + echo "Image to scan: $IMAGE" + echo "IMAGE=$IMAGE" >> "$GITHUB_OUTPUT" + + - name: Fetch Wiz credentials from AKeyless + id: fetch-secrets + uses: LanceMcCarthy/akeyless-action@ca2424bb132118c0b907f38e6dae0475acc0fac4 # v5.2.1 + with: + access-id: "p-5g555fgryzj2om" + static-secrets: '{"/ProductSecurity/Tools/WIZ_CLIENT_ID":"WIZ_CLIENT_ID","/ProductSecurity/Tools/WIZ_CLIENT_SECRET":"WIZ_CLIENT_SECRET"}' + + - name: Download Wiz CLI + run: | + curl -fsSL -o wizcli https://downloads.wiz.io/v1/wizcli/latest/wizcli-linux-amd64 + chmod +x wizcli + + - name: Wiz CLI container image scan + id: wiz-scan + continue-on-error: ${{ inputs.fail-build != true }} + env: + WIZ_CLIENT_ID: ${{ steps.fetch-secrets.outputs.WIZ_CLIENT_ID }} + WIZ_CLIENT_SECRET: ${{ steps.fetch-secrets.outputs.WIZ_CLIENT_SECRET }} + run: | + set -o pipefail + + SCAN_TYPE='container-image' + SCAN_TARGET='${{ steps.build-image.outputs.IMAGE }}' + + case "$SCAN_TYPE" in + dir|container-image) + ;; + *) + echo "Invalid scan-type: '$SCAN_TYPE'. Allowed values are 'dir' or 'container-image'." >&2 + exit 1 + ;; + esac + + args=("$SCAN_TYPE") + if [ -n "$SCAN_TARGET" ]; then + args+=("$SCAN_TARGET") + fi + + ./wizcli scan "${args[@]}" 2>&1 | tee /tmp/wiz-scan-results.txt + EXIT_CODE=${PIPESTATUS[0]} + + if [ $EXIT_CODE -eq 0 ]; then + echo "scan-result=passed" >> $GITHUB_OUTPUT + else + echo "scan-result=failed" >> $GITHUB_OUTPUT + fi + exit $EXIT_CODE + + - name: Write Job Summary + if: always() + run: | + RESULT="${{ steps.wiz-scan.outputs.scan-result }}" + if [ "$RESULT" = "passed" ]; then + ICON="✅" + else + ICON="❌" + fi + + { + echo "## ${ICON} Wiz CLI Scan Results" + echo "" + echo "| Field | Value |" + echo "|-------|-------|" + echo "| **Scan type** | \`container-image\` |" + echo "| **Target** | \`${{ steps.build-image.outputs.IMAGE }}\` |" + echo "| **Result** | **${RESULT}** |" + echo "" + echo "### Scan Output" + echo '```' + cat /tmp/wiz-scan-results.txt 2>/dev/null || echo "(no output captured)" + echo '```' + } >> "$GITHUB_STEP_SUMMARY" \ No newline at end of file