diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 07acfb30..2f00cc5d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,3 +1,4 @@ +--- # Dependabot configuration # # Grouping policy (aligned with microsoft/hve-core, optimized for fewer PRs): diff --git a/.github/workflows/pr-validation.yml b/.github/workflows/pr-validation.yml index 47b8aad9..ddfa699b 100644 --- a/.github/workflows/pr-validation.yml +++ b/.github/workflows/pr-validation.yml @@ -403,6 +403,7 @@ jobs: - code-quality-lint - powershell-lint - security-scan + - permissions-scan - yaml-lint - docs-automation - docusaurus-tests diff --git a/.github/workflows/security-scan.yml b/.github/workflows/security-scan.yml index 8786e1d8..f4580d3d 100644 --- a/.github/workflows/security-scan.yml +++ b/.github/workflows/security-scan.yml @@ -105,6 +105,16 @@ jobs: set -euo pipefail if ! grype dir:. --config .grype.yaml 2>&1 | tee security-results/grype-results.txt; then echo "GRYPE_FAILED=true" >> "$GITHUB_ENV" + + first_finding=$(awk ' + / fixed in / || /GO-[0-9]{4}-[0-9]+/ || /(Critical|High)/ {print; exit} + ' security-results/grype-results.txt) + + if [ -n "${first_finding}" ]; then + echo "::error title=Grype vulnerability threshold failed::${first_finding}" + else + echo "::error title=Grype vulnerability threshold failed::Grype found vulnerabilities at or above the .grype.yaml fail-on-severity threshold" + fi fi - name: Setup Node.js @@ -156,6 +166,22 @@ jobs: fi if [ "${GRYPE_FAILED:-}" = "true" ]; then echo "- :x: Grype: vulnerabilities found" + echo "" + echo "### Grype failure details" + echo "" + echo "Grype failed because at least one discovered vulnerability met or exceeded the .grype.yaml fail-on-severity threshold." + echo "" + if [ -s security-results/grype-results.txt ]; then + echo '```text' + awk ' + /^NAME[[:space:]]+/ {print; next} + / fixed in / || /GO-[0-9]{4}-[0-9]+/ || /(Critical|High)/ {print} + ' security-results/grype-results.txt | head -n 40 + echo '```' + echo "Full output is available in the security-scan-results artifact at security-results/grype-results.txt." + else + echo "No Grype output file was captured." + fi else echo "- :white_check_mark: Grype: passed" fi @@ -167,7 +193,7 @@ jobs: } >> "$GITHUB_STEP_SUMMARY" - name: Fail on Security Violations - if: always() && (env.GITLEAKS_FAILED == 'true' || env.GRYPE_FAILED == 'true' || env.SECRETLINT_FAILED == 'true') + if: always() shell: bash env: SOFT_FAIL: ${{ inputs.soft-fail }} @@ -182,13 +208,25 @@ jobs: echo "::warning::Grype vulnerabilities found (grype-soft-fail enabled, Gitleaks/Secretlint remain enforced)" else HARD_FAILURE="true" + echo "::group::Grype failure details" + echo "Grype found vulnerabilities at or above the .grype.yaml fail-on-severity threshold." + echo "Top Grype findings:" + if [ -s security-results/grype-results.txt ]; then + awk ' + /^NAME[[:space:]]+/ {print; next} + / fixed in / || /GO-[0-9]{4}-[0-9]+/ || /(Critical|High)/ {print} + ' security-results/grype-results.txt | head -n 40 + else + echo "No Grype output file was captured." + fi + echo "::endgroup::" fi fi if [ "$HARD_FAILURE" = "true" ]; then if [ "$SOFT_FAIL" = "true" ]; then echo "::warning::Security scan violations found (soft-fail enabled)" else - echo "::error::Security scan violations found" + echo "::error title=Security scan violations found::Review the failing scanner details above and the security scan job summary." exit 1 fi fi diff --git a/.github/workflows/workflow-permissions-scan.yml b/.github/workflows/workflow-permissions-scan.yml index 06bad16f..21c66ec9 100644 --- a/.github/workflows/workflow-permissions-scan.yml +++ b/.github/workflows/workflow-permissions-scan.yml @@ -1,3 +1,4 @@ +--- # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # Vendored from microsoft/hve-core@e158d88237e6b5e0fb57cb707dfc82410aa86702 diff --git a/scripts/build/Invoke-BicepLint.ps1 b/scripts/build/Invoke-BicepLint.ps1 index cbb1b206..d97fe57f 100644 --- a/scripts/build/Invoke-BicepLint.ps1 +++ b/scripts/build/Invoke-BicepLint.ps1 @@ -409,6 +409,10 @@ function Write-GitHubBicepOutput { "failures=$Failures" | Add-Content -Path $env:GITHUB_OUTPUT -Encoding UTF8 } + if ($Failures -gt 0 -and -not [string]::IsNullOrWhiteSpace($env:GITHUB_ENV)) { + 'BICEP_LINT_FAILED=true' | Add-Content -Path $env:GITHUB_ENV -Encoding UTF8 + } + if (-not [string]::IsNullOrWhiteSpace($env:GITHUB_STEP_SUMMARY)) { $Summary | Add-Content -Path $env:GITHUB_STEP_SUMMARY -Encoding UTF8 }