Skip to content

ci: add Trivy security scan to PR pipeline - #63

Draft
yaroslavmokflmg wants to merge 8 commits into
masterfrom
security/trivy
Draft

ci: add Trivy security scan to PR pipeline#63
yaroslavmokflmg wants to merge 8 commits into
masterfrom
security/trivy

Conversation

@yaroslavmokflmg

@yaroslavmokflmg yaroslavmokflmg commented Aug 3, 2026

Copy link
Copy Markdown

Adds a Trivy-based PR security gate:

  • scans repository dependencies (lockfiles / pom.xml) and Dockerfile base images
  • fails the pipeline on HIGH/CRITICAL vulnerabilities with a fix available
  • findings are deduplicated across modules; suppressions go to .trivyignore with a justification comment
  • wired into All Checks so merging is blocked when the scan is red

Summary by CodeRabbit

  • New Features
    • Added automated security scanning for repository files, dependencies, and container base images.
    • Pull requests are now checked for unfixed high- and critical-severity vulnerabilities.
  • Bug Fixes
    • Checks fail when qualifying vulnerabilities are detected, helping prevent insecure changes from being merged.
  • Documentation
    • Added guidance for excluding acknowledged vulnerabilities from scans.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c425d2e9-8072-4ecd-a813-79f7645b9635

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request adds a composite Trivy action. The action resolves Maven dependencies, scans repository files and Dockerfile base images, aggregates findings, and fails on unfixed HIGH or CRITICAL vulnerabilities. A pull-request workflow job runs the scan and gates all-checks.

Changes

Trivy security scanning

Layer / File(s) Summary
Scan action setup
.github/steps/trivy/action.yml
The composite action accepts optional Maven authentication, installs a pinned Trivy version, and resolves Maven dependencies.
Scan and aggregate findings
.github/steps/trivy/action.yml
The action scans filesystem dependencies and Dockerfile base images, merges reports, deduplicates findings, prints counts, and fails when vulnerabilities exist.
Pull request check integration
.github/workflows/test.yml, .trivyignore
The workflow runs trivy_scan for eligible pull requests with read-only permissions. all-checks waits for the scan. .trivyignore documents the exclusion format.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant PullRequest
  participant trivy_scan
  participant TrivyAction
  participant Maven
  participant Trivy
  PullRequest->>trivy_scan: trigger eligible pull request job
  trivy_scan->>TrivyAction: run shared scan action
  TrivyAction->>Maven: resolve project dependencies
  TrivyAction->>Trivy: scan files and Dockerfile base images
  Trivy-->>TrivyAction: return vulnerability reports
  TrivyAction-->>trivy_scan: return scan status
  trivy_scan-->>PullRequest: publish job result
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the addition of a Trivy security scan to the pull request pipeline.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch security/trivy

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/steps/trivy/action.yml:
- Around line 62-67: Update the trivy image-scan failure branch in the loop
around the `trivy image` command to exit nonzero when scanning a concrete image
fails, instead of always echoing and continuing. Preserve the existing skip
behavior for `scratch` and unresolved image variables by ensuring those cases
are filtered before this failure path.
- Around line 13-17: Update the Install Trivy step’s uses reference from the
mutable aquasecurity/setup-trivy@v0.3.1 tag to a reviewed, immutable
40-character commit SHA, keeping the existing version and cache inputs
unchanged.
- Around line 37-39: Update the Maven arguments in the dependency-resolution
step to remove the -fn flag, and make the mvn invocation propagate
dependency:go-offline failures instead of converting them into a warning.
Preserve the existing arguments and optional .mvn/settings.xml handling.

In @.github/workflows/test.yml:
- Around line 45-56: Update the trivy_scan workflow so fork pull requests never
run tokenized Maven dependency resolution: disable credential persistence in the
Checkout step and remove or conditionally skip the Trivy composite action’s
Maven resolution for fork-originated pull requests, while preserving it for
same-repository pull requests as appropriate.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 241c476c-3c1b-40af-99ff-2237a53055a1

📥 Commits

Reviewing files that changed from the base of the PR and between cad646d and bb5d9b7.

📒 Files selected for processing (3)
  • .github/steps/trivy/action.yml
  • .github/workflows/test.yml
  • .trivyignore

Comment on lines +13 to +17
- name: Install Trivy
uses: aquasecurity/setup-trivy@v0.3.1
with:
version: v0.73.0
cache: true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ref="$(awk '/uses: aquasecurity\/setup-trivy@/ {print $2}' .github/steps/trivy/action.yml)"
[[ "$ref" =~ ^aquasecurity/setup-trivy@[0-9a-f]{40}$ ]]

Repository: flamingo-stack/meshcentral

Length of output: 164


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "## action.yml relevant lines"
sed -n '1,45p' .github/steps/trivy/action.yml

echo
echo "## current Trivy pin"
ref="$(awk '/uses: aquasecurity\/setup-trivy@/ {print $2}' .github/steps/trivy/action.yml)"
printf 'pin=%s\n' "$ref"
[[ "$ref" =~ ^aquasecurity/setup-trivy@[0-9a-f]{40}$ ]]
exit_code=$?
echo "matches_40_char_sha=$exit_code"

Repository: flamingo-stack/meshcentral

Length of output: 2174


🌐 Web query:

aquasecurity setup-trivy advisory GHSA-69fq-xp46-6x23 March 2026 full commit SHA pin recommendation

💡 Result:

In response to the supply chain compromise identified as GHSA-69fq-xp46-6x23 (CVE-2026-33634) in March 2026, where a threat actor force-pushed malicious code to all existing tags (v0.2.0–v0.2.6) of the aquasecurity/setup-trivy GitHub Action, users are strongly advised to pin to a verified, safe commit SHA [1][2][3]. The specific commit SHA identified as the safe version for setup-trivy v0.2.6 following the incident is 3fb12ec12f41e471780db15c232d5dd185dcb514 [4][5]. Security best practices for using GitHub Actions, particularly following this incident, include: 1. Pinning to full, immutable commit SHA hashes rather than relying on mutable version tags (e.g., v0.2.6) to prevent similar supply chain attacks where tags are overwritten [6][3]. 2. Treating any pipeline secrets used during the exposure window (March 19, 2026, 17:43 UTC to approximately March 19, 2026, 21:44 UTC for setup-trivy) as compromised and rotating them immediately [1][4][2]. For additional context, aquasecurity restored setup-trivy v0.2.6 with safe content after the incident, but because the attacker force-pushed to the tags, users who had previously cached or pulled the malicious version of v0.2.6 must ensure they update to the corrected SHA [1][2].

Citations:


Pin aquasecurity/setup-trivy to a full commit SHA.

The pin aquasecurity/setup-trivy@v0.3.1 uses a mutable third-party action tag. A changed tag can execute code with the Maven token. Use a reviewed 40-character commit SHA instead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/steps/trivy/action.yml around lines 13 - 17, Update the Install
Trivy step’s uses reference from the mutable aquasecurity/setup-trivy@v0.3.1 tag
to a reviewed, immutable 40-character commit SHA, keeping the existing version
and cache inputs unchanged.

Comment thread .github/steps/trivy/action.yml Outdated
Comment on lines +37 to +39
margs=(-B -q -fn -DskipTests -gs /tmp/central-mirror.xml dependency:go-offline)
[ -f .mvn/settings.xml ] && margs+=(-s .mvn/settings.xml)
mvn "${margs[@]}" || echo "::warning::Maven dependency resolution incomplete; pom.xml scan depth may be reduced"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

mvn --help | grep -F -- '--fail-never'

Repository: flamingo-stack/meshcentral

Length of output: 201


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Locate action file and surrounding content"
if [ -f .github/steps/trivy/action.yml ]; then
  nl -ba .github/steps/trivy/action.yml | sed -n '1,120p'
else
  echo ".github/steps/trivy/action.yml not found"
fi

echo
echo "Search for action usage and related Trivy step files"
rg -n "trivy|dependency:go-offline|-fn|--fail-never|go-offline" .github pom.xml 2>/dev/null || true

Repository: flamingo-stack/meshcentral

Length of output: 247


🌐 Web query:

Maven fail-never option documentation "--fail-never" "never fail the build"

💡 Result:

The Maven --fail-never (or -fn) option is a command-line flag that instructs Maven to never fail the build, regardless of the project's result [1][2]. Key characteristics of this option include: - Behavior: When this option is used, even if individual modules or tasks within a multi-module project encounter errors or failures, Maven will continue processing the remaining modules in the reactor and report the overall build as a success [3][4][5]. - Usage: It is primarily intended for use in multi-module builds where you want to ensure all modules are processed or checked, regardless of whether some fail [2][5]. - Distinction from Test Failures: It is important to distinguish --fail-never from configuration properties like -Dmaven.test.failure.ignore=true [6]. While --fail-never influences the lifecycle behavior of the reactor (preventing build-level failure), it does not specifically silence test failures; individual tests may still report as failures in the logs, but the overall build status remains success [6][5]. This option is often utilized in continuous integration environments where you want to collect results from all modules even if one encounters an issue during the process [2][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -u

echo "Locate action file and surrounding content"
if [ -f .github/steps/trivy/action.yml ]; then
  awk '{printf "%6d\t%s\n", NR, $0}' .github/steps/trivy/action.yml | sed -n '1,140p'
else
  echo ".github/steps/trivy/action.yml not found"
fi

echo
echo "Search for action usage and related Trivy step files"
rg -n "trivy|dependency:go-offline|-fn|--fail-never|go-offline" .github pom.xml 2>/dev/null || true

echo
echo "Shell check: whether current maven command exists"
command -v mvn || true

Repository: flamingo-stack/meshcentral

Length of output: 6332


Fail the gate when Maven dependency resolution fails.

With set -euo pipefail, mvn should fail the step on dependency:go-offline errors, but -fn forces Maven to return success. Remove -fn and do not downgrade mvn failures to warnings.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/steps/trivy/action.yml around lines 37 - 39, Update the Maven
arguments in the dependency-resolution step to remove the -fn flag, and make the
mvn invocation propagate dependency:go-offline failures instead of converting
them into a warning. Preserve the existing arguments and optional
.mvn/settings.xml handling.

Comment thread .github/steps/trivy/action.yml Outdated
Comment on lines +62 to +67
if trivy image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --format json -o img.json "$img"; then
jq --arg s "$img" '.Results = ((.Results // []) | map(. + {ScanSrc: ("image " + $s)}))' img.json > img2.json
jq -s '{Results: (.[0].Results + (.[1].Results // []))}' combined.json img2.json > tmp.json && mv tmp.json combined.json
else
echo "skip ${img}"
fi

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Fail closed for a concrete base image that cannot be scanned.

Line 66 suppresses every image-scan failure. A pull request can change FROM to an unreachable concrete image and receive a passing security gate when the filesystem scan is clean. Keep the existing skips for scratch and unresolved variables, but exit nonzero after a trivy image failure.

Proposed fix
           else
-            echo "skip ${img}"
+            echo "::error::Unable to scan base image ${img}"
+            exit 1
           fi
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if trivy image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --format json -o img.json "$img"; then
jq --arg s "$img" '.Results = ((.Results // []) | map(. + {ScanSrc: ("image " + $s)}))' img.json > img2.json
jq -s '{Results: (.[0].Results + (.[1].Results // []))}' combined.json img2.json > tmp.json && mv tmp.json combined.json
else
echo "skip ${img}"
fi
if trivy image --scanners vuln --severity HIGH,CRITICAL --ignore-unfixed --format json -o img.json "$img"; then
jq --arg s "$img" '.Results = ((.Results // []) | map(. + {ScanSrc: ("image " + $s)}))' img.json > img2.json
jq -s '{Results: (.[0].Results + (.[1].Results // []))}' combined.json img2.json > tmp.json && mv tmp.json combined.json
else
echo "::error::Unable to scan base image ${img}"
exit 1
fi
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/steps/trivy/action.yml around lines 62 - 67, Update the trivy
image-scan failure branch in the loop around the `trivy image` command to exit
nonzero when scanning a concrete image fails, instead of always echoing and
continuing. Preserve the existing skip behavior for `scratch` and unresolved
image variables by ensuring those cases are filtered before this failure path.

Comment on lines +45 to +56
permissions:
contents: read
packages: read
if: github.event_name == 'pull_request' && github.event.pull_request.state == 'open' && !github.event.pull_request.draft
steps:
- name: Checkout
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha }}

- name: Trivy scan (fs + base images)
uses: ./.github/steps/trivy

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n -C 4 \
  'head\.repo|persist-credentials|maven-token|GITHUB_TOKEN|dependency:go-offline' \
  .github/workflows/test.yml .github/steps/trivy/action.yml

Repository: flamingo-stack/meshcentral

Length of output: 2778


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow relevant lines =="
sed -n '1,110p' .github/workflows/test.yml | cat -n

echo
echo "== trivy action relevant lines =="
sed -n '1,80p' .github/steps/trivy/action.yml | cat -n

echo
echo "== workflow references to head repo / forks / persist-credentials =="
rg -n 'pull_request|fork|persist-credentials|maven-token|GITHUB_TOKEN|actions/checkout|trivy' .github/workflows/test.yml .github/steps/trivy/action.yml

Repository: flamingo-stack/meshcentral

Length of output: 10873


Do not run Maven dependency resolution for fork pull requests.

The trivy_scan job runs for all open non-draft pull requests and checks out the pull request head. actions/checkout stores credentials by default, and the Trivy composite action exports GITHUB_TOKEN to Maven during dependency:go-offline. Maven can load pull-request-controlled build configuration such as .mvn/extensions.xml, so a fork PR could use that configuration to read the token. Set persist-credentials: false, remove Maven resolution from fork workflows, or scope tokenized Maven resolution to same-repository pull requests.

🧰 Tools
🪛 zizmor (1.28.0)

[warning] 50-53: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/test.yml around lines 45 - 56, Update the trivy_scan
workflow so fork pull requests never run tokenized Maven dependency resolution:
disable credential persistence in the Checkout step and remove or conditionally
skip the Trivy composite action’s Maven resolution for fork-originated pull
requests, while preserving it for same-repository pull requests as appropriate.

Source: Linters/SAST tools

@yaroslavmokflmg
yaroslavmokflmg marked this pull request as draft August 3, 2026 17:52
@yaroslavmokflmg yaroslavmokflmg self-assigned this Aug 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant