Skip to content

ci(security): SAST, secret and SCA gates - #225

Merged
ktursunov merged 2 commits into
mainfrom
ci/security-gates-sast-sca-secrets
Jul 29, 2026
Merged

ci(security): SAST, secret and SCA gates#225
ktursunov merged 2 commits into
mainfrom
ci/security-gates-sast-sca-secrets

Conversation

@Gregory91G

@Gregory91G Gregory91G commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Adds the three scanning domains this repository had none of: static analysis, secret detection, and software-composition analysis over both the source tree and the built image.

semgrep.yml is a port of constructorfabric/insight's workflow so findings stay comparable across the two repos, minus the p/rust / p/csharp packs (no Rust or C# here).

Rollout state per gate

Driven by the measured baseline, not by a uniform policy:

Gate Blocks? Baseline today
sast (Semgrep) no 17 findings, 0 at error level, 1 in src/ and that one is a false positive
gate (Trivy fs, CRITICAL) yes 0 CRITICAL — starts green
report (Trivy fs, HIGH/MED/LOW) no 10 HIGH / 16 MEDIUM / 3 LOW
trivy-image (docker.yml) no unknown until the first run — the base image has never been scanned
secrets (TruffleHog) yes 0 findings over all 62 refs

TruffleHog blocks from the start because there is nothing to triage. Semgrep and the Trivy report pass ratchet to blocking later: add --error for Semgrep, --exit-code 1 plus trivy-image in dispatch-umbrella's needs to bar a vulnerable image from promotion.

Two decisions worth reviewing

--results=verified,unknown,unverified,filtered_unverified on TruffleHog. The default (verified,unknown) suppresses findings whose live verification fails, so an already-revoked or inactive credential in the history produces a green run — on a public repository that is still a leak requiring rotation. Verified against a control repository with a planted key: with the default flags TruffleHog found it and reported nothing; with all four result kinds it reported detector, commit and path.

No raw secret value reaches a log, a job summary or an artifact. Actions logs and Code Scanning alerts are world-readable on a public repo, so echoing a hit would publish the value the gate exists to protect. The summary carries detector, commit and path only. For the same reason the Trivy report pass drops the secret scanner before uploading SARIF (--scanners vuln,misconfig) and secrets stay in the blocking gate.

Scanner images are digest-pinned and every action is SHA-pinned, so these files add no findings to the rules they run — confirmed by diffing Semgrep output before and after.

Test plan

Everything below was run locally against this branch.

  • YAML parses for all five workflows
  • actionlint (with shellcheck over run: blocks) — no findings in the new or changed code. Two pre-existing SC2046 warnings remain on Create multi-arch manifest and push (docker.yml), untouched
  • Trivy gate, exact command from the workflow — exit 0 (pnpm-lock.yaml: 0 CRITICAL, Dockerfile: 0 CRITICAL)
  • Trivy report pass — exit 0, SARIF and JSON both produced
  • Trivy summary script, extracted verbatim from the YAML and run against real output — renders 29 vulnerabilities and 2 misconfigurations, grouped by package
  • TruffleHog, exact pinned command with the read-only mount — exit 0, 0 findings, 6906 chunks over 407 commits
  • TruffleHog summary script against a planted secret — exits 1, prints detector / commit / path, prints no secret value
  • Same script against the clean repository — exits 0
  • Semgrep with the new .semgrepignore — 17 findings over 438 targets, down from 21 over 579
  • Semgrep before/after diff — the new files introduce zero findings
  • trivy-image against the published manifest — needs a pushed tag, so it first runs on merge to main
  • SARIF upload to Code Scanning — confirmed on this PR's own run: Semgrep OSS 17 results and Trivy 31 results (29 CVEs + 2 misconfigurations) recorded against refs/pull/225/merge

GitHub re-ranks Semgrep severity from rule metadata rather than the SARIF level, so four alerts land at error severity: missing-user and missing-user-entrypoint (Dockerfile:30-31), run-shell-injection (ci.yml:166) and use-defused-xml-parse (scripts/ci/coverage-summary.py:58). The remaining 13 - all mutable action tags - are warnings.

Note

Code Scanning upload is free while this repository is public. If it returns to private, the three upload-sarif steps will fail without GitHub Advanced Security; the job-summary reports would keep working.

Summary by CodeRabbit

  • Security
    • Added automated security scanning for source code, dependencies, container images, and secrets (SAST, SCA, and full-history secret detection).
    • High/medium/low scans provide reports, while critical findings and detected secrets can block the workflow.
    • Security findings are summarized in job results and uploaded to code-scanning for review (SARIF where applicable).
  • Chores
    • Updated ignore rules to exclude generated scanner outputs and common build/cache artifacts from version control and scanning.

Refs constructorfabric/insight#2079

@Gregory91G
Gregory91G requested a review from a team as a code owner July 28, 2026 14:45
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds CI security scanning for source code, dependencies, secrets, repository configuration, and published container images, with blocking critical checks, report-only scans, Code Scanning uploads, job summaries, and ignored generated report files.

Changes

Security scanning automation

Layer / File(s) Summary
Semgrep SAST reporting
.github/workflows/semgrep.yml, .semgrepignore
Runs digest-pinned Semgrep scans, summarizes SARIF findings, uploads results when permitted, and excludes generated or vendored paths.
Trivy filesystem gate and reporting
.github/workflows/trivy.yml, .gitignore
Adds a blocking critical-severity scan plus non-blocking SARIF and JSON reports for lower severities, with summaries and ignored generated outputs.
TruffleHog history scanning
.github/workflows/trufflehog.yml
Scans reachable Git history, summarizes redacted metadata, and fails when findings are present.
Published image scanning
.github/workflows/docker.yml
Scans the newly published GHCR multi-architecture image on default-branch publishing events and uploads report-only SARIF results.

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

Possibly related PRs

🚥 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 accurately reflects the main change: adding CI security scanning for SAST, secrets, and SCA.
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 ci/security-gates-sast-sca-secrets

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.

@github-advanced-security

Copy link
Copy Markdown

You are seeing this message because GitHub Code Scanning has recently been set up for this repository, or this pull request contains the workflow file for the Code Scanning tool.

What Enabling Code Scanning Means:

  • The 'Security' tab will display more code scanning analysis results (e.g., for the default branch).
  • Depending on your configuration and choice of analysis tool, future pull requests will be annotated with code scanning analysis results.
  • You will be able to see the analysis results for the pull request's branch on this overview once the scans have completed and the checks have passed.

For more information about GitHub Code Scanning, check out the documentation.

Three scanning domains, none of them covered before: Semgrep for static
analysis, TruffleHog for secrets, Trivy for dependencies and the built image.
semgrep.yml mirrors constructorfabric/insight's so findings stay comparable
across repos, minus the p/rust and p/csharp packs.

Rollout state differs per gate, driven by the measured baseline:

  - Semgrep: report-only (17 findings, 0 error level). Ratchets to blocking
    with --error once triaged.
  - Trivy fs: gate blocks on CRITICAL (baseline 0), report pass covers
    HIGH/MEDIUM/LOW (baseline 10/16/3) without blocking.
  - Trivy image: report-only, in docker.yml where the pushed manifest tag is
    available. Base-image and OS-package CVEs are invisible to the fs pass.
  - TruffleHog: blocking from the start. The baseline is provably empty over
    all 62 refs, so there is nothing to triage.

TruffleHog runs with --results=verified,unknown,unverified,filtered_unverified.
The default set hides findings that fail live verification, so a revoked or
inactive credential in the history yields a green run — on a public repository
that is still a leak.

No raw secret value reaches a log, a job summary or an artifact: Actions logs
and Code Scanning alerts are world-readable here. The summary carries detector,
commit and path only. For the same reason the Trivy report pass drops the
secret scanner before uploading SARIF and keeps secrets in the blocking gate.

Scanner images are digest-pinned and actions are SHA-pinned, so these files add
no findings to the very rules they run.

Signed-off-by: Grigoriy Gogin <Grigoriy.Gogin@constructor.tech>
@Gregory91G
Gregory91G force-pushed the ci/security-gates-sast-sca-secrets branch from c7ddade to 71714fe Compare July 28, 2026 14:48

@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: 5

🧹 Nitpick comments (5)
.github/workflows/trivy.yml (3)

43-45: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

TRIVY_IMAGE digest duplicated with docker.yml.

The exact same digest-pinned string is repeated in docker.yml (Line 192). Two independent places to update on the next Trivy bump invites drift. See consolidated comment.

🤖 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/trivy.yml around lines 43 - 45, Consolidate the duplicated
TRIVY_IMAGE value by defining it in one shared configuration location and
reference that value from both trivy.yml and docker.yml. Remove the
independently hardcoded digest while preserving the existing digest-pinned Trivy
image behavior.

1-1: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Digest-pinned TRIVY_IMAGE is duplicated verbatim across two workflow files. A future Trivy version/digest bump requires remembering to update both locations in lockstep, or the two workflows silently drift onto different scanner versions.

  • .github/workflows/trivy.yml#L43-45: keep as the canonical declaration, or move to a shared repo/org-level Actions variable.
  • .github/workflows/docker.yml#L191-192: reference the same shared variable (e.g. vars.TRIVY_IMAGE) instead of a second hard-coded copy.
🤖 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/trivy.yml at line 1, Eliminate the duplicated hard-coded
TRIVY_IMAGE declaration in the Docker workflow by referencing the canonical
declaration from the Trivy workflow or an appropriate shared Actions variable
such as vars.TRIVY_IMAGE. Keep one authoritative digest-pinned value and update
the Docker workflow’s Trivy invocation to consume it.

73-109: 🧹 Nitpick | 🔵 Trivial

No cross-run caching of the Trivy vulnerability DB.

/tmp/trivy-cache is only reused within the same job's two docker run invocations; it isn't persisted between separate workflow runs (no actions/cache step). Given this workflow fires on every PR, push, and nightly cron, each run re-downloads the DB from the public ghcr.io/aquasecurity/trivy-db mirror, adding latency and exposure to anonymous pull-rate limiting. Worth wiring an actions/cache step keyed on a date/version to persist /tmp/trivy-cache (or the DB's own cache dir) across runs — applies equally to the gate job (which currently has no cache mount at all) and to docker.yml's trivy-image job.

🤖 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/trivy.yml around lines 73 - 109, Persist the Trivy cache
across workflow runs by adding an actions/cache step keyed by an appropriate
date or Trivy database version, targeting /tmp/trivy-cache before the report
scans execute. Apply the same cache setup and mount usage to the gate job, and
update the trivy-image job in docker.yml to reuse its persisted database cache.
.github/workflows/docker.yml (2)

191-192: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Duplicated TRIVY_IMAGE pin — see consolidated comment.

🤖 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/docker.yml around lines 191 - 192, Remove the duplicated
TRIVY_IMAGE definition from the workflow and retain a single pinned value for
the Trivy image, consolidating references to use that existing definition.

169-231: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value

Make the .trivyignore checkout comment match the Trivy invocation.

The table scan has no repository mount, so the checkout step’s “waivers” note doesn’t apply to that invocation. The SARIF scan already mounts ${{ github.workspace }}:/work, so if waivers are intended here, run Trivy from /work or pass --ignorefile /work/.trivyignore; otherwise remove the waiver-related justification from the checkout permission comment.

🤖 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/docker.yml around lines 169 - 231, Update the trivy-image
workflow’s checkout permission comment and Trivy invocations so the
`.trivyignore` justification matches actual usage: either make both scans access
the checked-out ignore file by running from `/work` or passing `--ignorefile
/work/.trivyignore`, or remove the “.trivyignore waivers” justification from the
contents permission if waivers are not intended.
🤖 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/workflows/semgrep.yml:
- Around line 91-93: Update the summary-writing logic around the Semgrep SAST
report so the Code scanning link and “full details” claim are included only when
the SARIF upload runs for non-fork pull requests; for fork PRs, state that Code
Scanning details are unavailable. Keep the finding count and report-only wording
unchanged.
- Around line 60-63: Update the Semgrep invocation in the workflow so all
enabled generic.secrets.* rules are excluded from the SARIF, not just
generic.secrets.security.detected-generic-secret. Use a non-secret rule set or
explicitly exclude every selected secret rule, then validate semgrep.sarif
contains no secret-related rule IDs before it is uploaded.

In @.github/workflows/trivy.yml:
- Around line 57-71: Update the Trivy invocation in the “Trivy fs scan —
CRITICAL only (blocking)” workflow step to explicitly load the workspace-root
waiver file by passing /src/.trivyignore via Trivy’s ignorefile option,
preserving the existing scan behavior and options.
- Line 1: Update every Trivy docker invocation in the workflow to explicitly
access the mounted .trivyignore file, using the matching workspace path (/src or
/work) via --ignorefile or an equivalent working directory setting. Ensure the
table-format image scan invocation also mounts the workspace and applies the
ignore file, preserving the existing scan behavior and output formats.

In @.github/workflows/trufflehog.yml:
- Around line 105-106: Update the TruffleHog summary generation around the
`git.get("file")` and `git.get("line")` fields so repository paths and line
values are not emitted to `GITHUB_STEP_SUMMARY`; report only the detector and
commit fields, while retaining local inspection of the commit for the exact
finding location.

---

Nitpick comments:
In @.github/workflows/docker.yml:
- Around line 191-192: Remove the duplicated TRIVY_IMAGE definition from the
workflow and retain a single pinned value for the Trivy image, consolidating
references to use that existing definition.
- Around line 169-231: Update the trivy-image workflow’s checkout permission
comment and Trivy invocations so the `.trivyignore` justification matches actual
usage: either make both scans access the checked-out ignore file by running from
`/work` or passing `--ignorefile /work/.trivyignore`, or remove the
“.trivyignore waivers” justification from the contents permission if waivers are
not intended.

In @.github/workflows/trivy.yml:
- Around line 43-45: Consolidate the duplicated TRIVY_IMAGE value by defining it
in one shared configuration location and reference that value from both
trivy.yml and docker.yml. Remove the independently hardcoded digest while
preserving the existing digest-pinned Trivy image behavior.
- Line 1: Eliminate the duplicated hard-coded TRIVY_IMAGE declaration in the
Docker workflow by referencing the canonical declaration from the Trivy workflow
or an appropriate shared Actions variable such as vars.TRIVY_IMAGE. Keep one
authoritative digest-pinned value and update the Docker workflow’s Trivy
invocation to consume it.
- Around line 73-109: Persist the Trivy cache across workflow runs by adding an
actions/cache step keyed by an appropriate date or Trivy database version,
targeting /tmp/trivy-cache before the report scans execute. Apply the same cache
setup and mount usage to the gate job, and update the trivy-image job in
docker.yml to reuse its persisted database cache.
🪄 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: b300e0a4-cf5b-4500-a700-66f64d125ff6

📥 Commits

Reviewing files that changed from the base of the PR and between f6bd345 and c7ddade.

📒 Files selected for processing (6)
  • .github/workflows/docker.yml
  • .github/workflows/semgrep.yml
  • .github/workflows/trivy.yml
  • .github/workflows/trufflehog.yml
  • .gitignore
  • .semgrepignore

Comment on lines +60 to +63
semgrep scan \
--config auto \
--exclude-rule generic.secrets.security.detected-generic-secret \
--sarif --output semgrep.sarif

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

echo "== workflow excerpt =="
sed -n '1,120p' .github/workflows/semgrep.yml

echo
echo "== repo Semgrep references =="
rg -n "semgrep|generic\.secrets|detected-generic-secret|sarif|CodeQL|Code Scanning" .github . 2>/dev/null | head -200

echo
echo "== search for Semgrep config files if any =="
git ls-files | grep -E '(^|/)semgrep|^\.semgrep|semgrep\.yaml|\.semgrepignore|\.semgrep$' || true

python3 - <<'PY'
from pathlib import Path
p=Path('.github/workflows/semgrep.yml')
text=p.read_text() if p.exists() else ''
for i,line in enumerate(text.splitlines(),1):
    if 'exclude-rule' in line or 'semgrep scan' in line or 'semgrep.sarif' in line:
        print(f'{p}:{i}:{line}')
PY

Repository: constructorfabric/insight-front

Length of output: 9846


🌐 Web query:

semgrep exclude rule rule ID short ID generic.secrets detected-generic-secret official documentation excludes

💡 Result:

To exclude a specific Semgrep rule—such as detected-generic-secret—from your scans, you can use several methods depending on whether you want to exclude it globally, via the command line, or for specific files [1][2][3]. The full rule ID for generic secret detection typically follows the format generic.secrets.security.detected-generic-secret (or a variation depending on your configuration source) [4][5]. You should verify the exact rule ID in your Semgrep dashboard or by inspecting the rule file [6][3]. Methods to exclude the rule: 1. Command-Line Interface (CLI): Use the --exclude-rule flag when running a scan [6][3]. This is the most direct way to ignore a rule globally for a specific execution [2]. semgrep scan --exclude-rule <rule_ID> 2. Inline Comments: To ignore the rule for specific lines of code, add a nosemgrep comment on the line preceding the finding [1][2][3]. // nosemgrep: <rule_ID> 3. Rule-Level Path Exclusion: If you want to keep the rule active but skip it for certain files or directories, you can modify the rule itself (or create a custom version) by adding a paths: exclude: section in the rule's YAML configuration [1][4][7]. rules: - id: <rule_ID>... paths: exclude: - "path/to/ignore/*" 4. Semgrep Platform: If you are using the Semgrep AppSec Platform, you can triage findings as false positives or ignored risks directly in the dashboard [2][8][3]. These decisions persist across future scans, preventing the finding from being reported again [3]. For maintaining consistent ignores across a project without using CLI flags, creating a custom rule that extends the original but adds a paths: exclude: filter is a common practice [4][2].

Citations:


🌐 Web query:

Semgrep CLI 1.170.0 help --exclude-rule rule ID generic.secrets.security.detected-generic-secret

💡 Result:

To exclude a specific rule by its ID when running Semgrep CLI, use the --exclude-rule flag followed by the rule ID [1][2]. Based on your query, the correct command syntax is: semgrep --exclude-rule generic.secrets.security.detected-generic-secret This flag can be used multiple times in a single command to exclude more than one rule [1]. For other ways to manage rule exclusions: - Inline comments: To ignore a specific rule in your code, you can add a comment with the nosemgrep annotation immediately before the flagged code (e.g., // nosemgrep: rule-id) [3][2]. - Rule configuration: You can edit the rule definition itself to include paths filters if you only want to exclude the rule on specific files or directories [3][4]. - Semgrep AppSec Platform: For secrets scans specifically, you can also manage ignores through the Semgrep AppSec Platform if applicable to your configuration [3]. The --exclude-rule flag is available in Semgrep CLI versions that support rule filtering by ID [5]. Since you are using version 1.170.0, this functionality is fully supported [1][6].

Citations:


🌐 Web query:

Semgrep docs --exclude-rule --exclude-prefix

💡 Result:

Semgrep does not have a flag named --exclude-prefix. It is likely you are confusing the standard --exclude flag with other command-line options. Below is a summary of how to use the available exclusion flags and related features: --exclude-rule <rule_ID> This flag is used to skip a specific rule during a scan [1][2][3]. It is useful for silencing noisy rules without removing them from your configuration [1]. You can specify this flag multiple times to exclude multiple rules [2][3]. --exclude This flag is used to skip files or directories that match a specified glob-style pattern [4][2][5]. The pattern syntax follows gitignore and semgrepignore conventions [4][5]. Like --exclude-rule, this flag can be specified multiple times in a single command [4][2][3]. Other Ways to Exclude or Include If you are looking for more granular control than command-line flags provide, Semgrep offers several alternatives: 1. Rule-level path filtering: Within a rule's configuration file (YAML), you can use the paths: key with include: or exclude: sub-keys to limit which files a specific rule runs on [6][7]. 2. Ignore files: You can create a.semgrepignore file in your project to persistently ignore specific files or directories across multiple scans [5][8]. 3. Inline suppression: You can use the # nosemgrep comment within your code to suppress findings on a per-line or per-file basis [1][7]. There is no command-line flag --exclude-prefix in Semgrep. If your goal was to exclude rules or paths based on a common prefix, you must provide the full rule ID or glob pattern, or use appropriate wildcard patterns (e.g., --exclude 'dir/*') within the supported --exclude flag [4][5].

Citations:


🌐 Web query:

Semgrep secrets rules generic.secrets auto config

💡 Result:

Semgrep’s generic secrets detection, often referred to as "Generic secrets AI" or "AI augmented rules," is a feature designed to detect potential credentials (such as API keys and passwords) by identifying common keywords and surrounding context rather than relying solely on specific, hardcoded patterns [1]. To configure and enable generic secrets, you do not use a local "auto config" file in the traditional sense; instead, the feature is enabled and managed directly through the Semgrep AppSec Platform [1]. How to enable Generic Secrets: 1. Sign in to the Semgrep AppSec Platform. 2. Navigate to Settings > General > Secrets [1]. 3. Locate the Generic secrets section and toggle the switch to "On" [1]. Once enabled, subsequent scans will automatically incorporate generic secrets rules [1]. You can verify that these rules are active by checking the CLI output during a scan, which will display a confirmation message stating: "AI augmented rules are active for secrets detection" [1]. Key aspects of Generic Secrets: - Analysis Method: Findings identified via this method are analyzed by "Semgrep Multimodal" to eliminate false positives and highlight high-signal, actionable results [1]. - Management: You can manage and filter these findings in the Semgrep AppSec Platform under the Findings page by selecting the "Generic" option in the "Secret type" filter [1]. - Policies: You can further control how your organization handles these secrets by navigating to Rules & policies > Policies > Secrets in the AppSec Platform, where you can filter by "Analysis method" to distinguish between Semantic and Generic analysis [2]. For standard secret detection, Semgrep also supports custom rules and validator configurations, which can be managed via the Semgrep Editor in the AppSec Platform [3][2][4].

Citations:


Exclude all enabled secret rules from the Semgrep SARIF.

--exclude-rule only excludes the single specified full rule ID; --config auto can select additional generic.secrets.* rules, and their findings are written to semgrep.sarif and uploaded to Code Scanning. Split this into a non-secret Semgrep rule set, or exclude every selected secret rule explicitly, then assert the generated SARIF contains no secret-related rule IDs.

🤖 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/semgrep.yml around lines 60 - 63, Update the Semgrep
invocation in the workflow so all enabled generic.secrets.* rules are excluded
from the SARIF, not just generic.secrets.security.detected-generic-secret. Use a
non-secret rule set or explicitly exclude every selected secret rule, then
validate semgrep.sarif contains no secret-related rule IDs before it is
uploaded.

Comment on lines +91 to +93
w("## Semgrep SAST (report-only)\n\n")
w(f"**{total}** finding(s) from `auto` (secrets excluded — TruffleHog owns those). "
f"This check does **not** block; full details in [Security -> Code scanning]({cs_url}).\n\n")

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files:"
git ls-files .github/workflows/semgrep.yml | sed -n '1,20p'

echo
echo "Relevant workflow section:"
if [ -f .github/workflows/semgrep.yml ]; then
  nl -ba .github/workflows/semgrep.yml | sed -n '1,180p'
else
  echo "missing .github/workflows/semgrep.yml"
fi

echo
echo "Search for Code scanning reference and fork SARIF behavior:"
rg -n "fork|pull_request|sarif|Code scanning|Code scanning|code scanning|secrets excluded|TruffleHog|check does" .github/workflows/semgrep.yml .github/workflows || true

Repository: constructorfabric/insight-front

Length of output: 275


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Relevant workflow section:"
if [ -f .github/workflows/semgrep.yml ]; then
  awk '{printf "%5d\t%s\n", NR, $0}' .github/workflows/semgrep.yml | sed -n '1,180p'
else
  echo "missing .github/workflows/semgrep.yml"
fi

echo
echo "Search for fork/SARIF/Code scanning references:"
grep -En "fork|pull_request|sarif|Code scanning|code scanning|secrets excluded|TruffleHog" .github/workflows/semgrep.yml .github/workflows || true

Repository: constructorfabric/insight-front

Length of output: 8271


Do not promise Code Scanning details for fork PRs.

The SARIF upload is skipped for fork pull requests, but the job summary always says full details are available in Security -> Code scanning. Make that wording and link conditional on the same upload condition, or state that details are unavailable for fork PRs.

🤖 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/semgrep.yml around lines 91 - 93, Update the
summary-writing logic around the Semgrep SAST report so the Code scanning link
and “full details” claim are included only when the SARIF upload runs for
non-fork pull requests; for fork PRs, state that Code Scanning details are
unavailable. Keep the finding count and report-only wording unchanged.

@@ -0,0 +1,169 @@
name: Trivy SCA

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== files =="
git ls-files | rg '(^|/)(\.github/workflows/trivy\.yml|\.github/workflows/docker\.yml|\.trivyignore|README|.*\.md)$' || true

echo "== trivy workflow =="
if [ -f .github/workflows/trivy.yml ]; then
  nl -ba .github/workflows/trivy.yml | sed -n '1,130p'
fi

echo "== docker workflow relevant =="
if [ -f .github/workflows/docker.yml ]; then
  nl -ba .github/workflows/docker.yml | sed -n '130,250p'
fi

echo "== trivyignore =="
if [ -f .trivyignore ]; then
  nl -ba .trivyignore | sed -n '1,120p'
fi

echo "== search trivy invocations =="
rg -n "docker run|trivy|ignorefile|-w\b|--ignorefile|checkout \(\.trivyignore waivers\)|contents: read" .github/workflows || true

Repository: constructorfabric/insight-front

Length of output: 6528


🌐 Web query:

Trivy .trivyignore default ignorefile location container working directory -w --ignorefile

💡 Result:

The default location for the Trivy ignore file is a file named.trivyignore located in the current working directory [1][2][3]. You can specify a different ignore file location using the --ignorefile flag [4][2][3]. When using this flag, you must provide the path to your custom ignore file [5]. Key considerations for using --ignorefile: - The path provided to --ignorefile should be reachable by the Trivy process [5]. - In containerized environments, if you are running Trivy as a container, ensure the ignore file is mounted into the container at the path you specify in the --ignorefile flag so that Trivy can access it [5]. - Trivy may not produce a warning or error if the file specified by --ignorefile does not exist or cannot be accessed, so ensure the path is correctly configured [6]. - Note that.trivyignore (and the --ignorefile mechanism) generally applies to scan results; for some scan types (like misconfigurations in specific file formats such as Terraform or Dockerfiles), Trivy also supports inline comments for ignoring specific issues [7].

Citations:


🌐 Web query:

Trivy CLI default ignorefile .trivyignore current directory --ignorefile

💡 Result:

In the Trivy CLI, the default behavior regarding ignore files is as follows: Default Ignore File By default, Trivy automatically looks for a file named.trivyignore in the current working directory [1][2]. This file is used to specify vulnerabilities, misconfigurations, or secrets to be ignored during a scan [3]. Using the --ignorefile Option You can specify a custom ignore file path using the --ignorefile flag [1][4]. 1. Usage: When you provide a path via --ignorefile, Trivy uses that specific file instead of the default.trivyignore [3][5]. 2. Strict Requirement: If you explicitly specify an ignore file using the --ignorefile flag, Trivy expects that file to exist [6]. If the specified file is missing, the scan will fail with a fatal error [6]. This differs from the default behavior, where the absence of a.trivyignore file in the current directory does not cause the scan to fail [6]. 3. Supported Formats: -.trivyignore: The legacy format (plain text) [3][5]. -.trivyignore.yaml (or.yml): A structured YAML format that allows for more granular control, such as ignoring findings based on file paths, PURLs, or expiration dates [3][5]. Note that if you are using the YAML format, you must explicitly provide the path using the --ignorefile flag [3][5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow file sizes =="
wc -l .github/workflows/trivy.yml .github/workflows/docker.yml 2>/dev/null || true

echo "== trivy workflow =="
sed -n '1L,180Lp' .github/workflows/trivy.yml 2>/dev/null | awk '{printf "%5d  %s\n", NR, $0}'

echo "== docker workflow relevant =="
sed -n '130L,260Lp' .github/workflows/docker.yml 2>/dev/null | awk '{printf "%5d  %s\n", NR, $0}'

echo "== trivyignore =="
if [ -f .trivyignore ]; then
  sed -n '1L,160Lp' .trivyignore | awk '{printf "%5d  %s\n", NR, $0}'
else
  echo ".trivyignore not found"
fi

echo "== relevant searches =="
rg -n "docker run|--scan|trivy|pull|image|repository|fs|sbom|ignorefile|--ignorefile|-w\b|checkout \(\.trivyignore waivers\)|contents: read|# checkout" .github/workflows || true

Repository: constructorfabric/insight-front

Length of output: 297


🌐 Web query:

aquasecurity/trivy docker run example --ignorefile .trivyignore volume mount -w workdir

💡 Result:

To use a.trivyignore file when running Trivy in a Docker container, you must mount the file into the container and point Trivy to it using the --ignorefile flag [1]. Example Docker Command To scan an image while using a.trivyignore file located in your current directory, use the following command: docker run --rm \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(pwd)/.trivyignore:/root/.trivyignore \ -v $HOME/Library/Caches:/root/.cache \ aquasec/trivy:latest image \ --ignorefile /root/.trivyignore \ Key Components: 1. Volume Mounts (-v): - /var/run/docker.sock:/var/run/docker.sock: Required to allow Trivy to communicate with the host's Docker daemon to scan images [2][3][1]. - $(pwd)/.trivyignore:/root/.trivyignore: Mounts your local ignore file into the container's filesystem [1]. - $HOME/Library/Caches:/root/.cache: Strongly recommended to persist the vulnerability database between scans, which significantly improves performance [2][3][4]. 2. Working Directory &amp; Ignore File: - The --ignorefile flag tells Trivy where to find the ignore configuration [5][6]. By mounting it to /root/.trivyignore and referencing that path, you ensure the scanner respects your exclusions [1]. - If you prefer scanning a filesystem (e.g., your source code) rather than an image, you can mount your project directory: -v $(pwd):/workspace, then set the working directory in the command: -w /workspace [7]. For consistent usage, you can also define the ignorefile path within a configuration file (e.g., trivy.yaml) instead of passing the flag every time [8][9][10].

Citations:


🌐 Web query:

site:trivy.dev "--ignorefile" "default" ".trivyignore"

💡 Result:

The --ignorefile flag in Trivy is used to specify a file that contains identifiers for vulnerabilities, misconfigurations, secrets, or licenses to be ignored during a scan [1][2]. By default, Trivy looks for a file named.trivyignore [3][4]. Key details regarding the --ignorefile option include: Supported Formats: Trivy supports both.trivyignore (plain text) and.trivyignore.yaml (YAML) files [1]. The YAML format allows for more granular control, such as specifying paths, package URLs (purls), and expiration dates for ignored findings [1]. Configuration File Usage: In addition to the command-line flag, you can set the ignore file path in your Trivy configuration file using the ignorefile setting [3][4]. Experimental Feature: While.trivyignore is standard, the use of.trivyignore.yaml is sometimes noted as requiring explicit specification via the --ignorefile flag, as it may be treated as an experimental feature depending on your specific version [1]. Distinction from Skipping: It is important to distinguish --ignorefile (which filters out specific findings/results) from flags like --skip-files or --skip-dirs (which control which files or directories Trivy traverses or scans entirely) [1][5].

Citations:


🏁 Script executed:

#!/bin/bash
set +e

echo "== shell env =="
printf 'SHELL=%s\nPWD=%s\n' "$SHELL" "$PWD"

echo "== files =="
git ls-files .github/workflows/trivy.yml .github/workflows/docker.yml .trivyignore README.md SECURITY.md CLAUDE.md 2>/dev/null

echo "== trivy workflow =="
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/trivy.yml")
print(f"exists={p.exists()} size={p.stat().st_size if p.exists() else 0}")
for i,line in enumerate(p.read_text(errors="replace").splitlines(),1):
    print(f"{i:5d} {line}")
PY

echo "== docker workflow =="
python3 - <<'PY'
from pathlib import Path
p = Path(".github/workflows/docker.yml")
print(f"exists={p.exists()} size={p.stat().st_size if p.exists() else 0}")
for i,line in enumerate(p.read_text(errors="replace").splitlines(),1):
    if 130 <= i <= 260:
        print(f"{i:5d} {line}")
PY

echo "== trivy workflow relevant search =="
python3 - <<'PY'
from pathlib import Path
txt = Path(".github/workflows/trivy.yml").read_text(errors="replace")
for needle in ["docker run", "trivy", "ignorefile", "contents: read", "checkout"]:
    print(f"\n-- {needle} --")
    for lineno, line in enumerate(txt.splitlines(), 1):
        if needle in line:
            start=max(1, lineno-3); end=min(len(txt.splitlines()), lineno+5)
            for sn in range(start, end+1):
                print(f"{sn:5d} {txt.splitlines()[sn-1]}")
PY

echo "== .trivyignore presence and lines =="
python3 - <<'PY'
from pathlib import Path
p = Path(".trivyignore")
print(f"exists={p.exists()} size={p.stat().st_size if p.exists() else 0}")
if p.exists():
    for i,line in enumerate(p.read_text(errors="replace").splitlines(),1):
        print(f"{i:5d} {line}")
PY

Repository: constructorfabric/insight-front

Length of output: 26025


🌐 Web query:

Trivy 0.72.0 default ignorefile --ignorefile .trivyignore .trivyignore.yaml

💡 Result:

In Trivy 0.72.0, the --ignorefile flag is used to specify the file containing ignore rules [1]. The default value for this flag, when it is not explicitly provided, is.trivyignore [1][2][3]. Key points regarding the behavior of --ignorefile: 1. Automatic vs. Explicit Loading: While Trivy automatically looks for.trivyignore in the working directory by default, files with the.yaml or.yml extension (such as.trivyignore.yaml) must generally be explicitly specified using the --ignorefile flag [4][5]. 2. File Parsing: Trivy detects the format based on the file extension [6]. If the specified file ends in.yaml or.yml, Trivy attempts to parse it as a structured YAML configuration [6][4]. Otherwise, it is parsed as a legacy.trivyignore file [6][5]. 3. Missing Files: If you provide a specific path via --ignorefile and the file does not exist, Trivy will treat this as an error and stop execution [7]. This behavior changed in recent versions to prevent silent misconfigurations in CI/CD pipelines [7][8]. If you need to support environments where the file might not be present, ensure the file is created or adjust your pipeline logic to handle its absence [7]. In summary, you do not need to set the flag if you are using the default.trivyignore [1][3]. If you are using.trivyignore.yaml or any other custom filename, you must use --ignorefile to ensure it is loaded correctly [4][5].

Citations:


Make .trivyignore accessible to each Trivy container

Trivy reads .trivyignore from the container’s working directory by default, but these docker run commands never set that directory; they run inside the image’s root directory while the workspace is mounted under /src//work. Add --ignorefile /src/.trivyignore/--ignorefile /work/.trivyignore (or --workingdir /src/--workingdir /work) to each invocation so the documented waiver workflow is not skipped end-to-end. Also don’t omit the mount from the table-format image scan at docker.yml:196-211.

🤖 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/trivy.yml at line 1, Update every Trivy docker invocation
in the workflow to explicitly access the mounted .trivyignore file, using the
matching workspace path (/src or /work) via --ignorefile or an equivalent
working directory setting. Ensure the table-format image scan invocation also
mounts the workspace and applies the ignore file, preserving the existing scan
behavior and output formats.

Comment on lines +57 to +71
- name: Trivy fs scan — CRITICAL only (blocking)
# `--ignore-unfixed` keeps the gate actionable: a CRITICAL with no released fix cannot
# be resolved by the PR author, so it belongs in the report pass, not in a merge block.
# Waivers go in `.trivyignore` at the repo root, date-scoped:
# CVE-2026-12345 exp:2026-12-31 # tracked in <issue>, fix queued
run: |
docker run --rm \
-v "${{ github.workspace }}:/src:ro" \
"$TRIVY_IMAGE" fs \
--scanners vuln,secret,misconfig \
--severity CRITICAL \
--ignore-unfixed \
--exit-code 1 \
--no-progress \
/src

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== candidate workflows =="
git ls-files '.github/workflows/*' | sed -n '1,120p'

echo
echo "== trivy workflow excerpt =="
if [ -f .github/workflows/trivy.yml ]; then
  nl -ba .github/workflows/trivy.yml | sed -n '1,120p'
fi

echo
echo "== docker workflow trivy mentions =="
rg -n -C 4 'trivy|TRIVY|--ignorefile|-w /src|docker run' .github/workflows docker.yml . 2>/dev/null | sed -n '1,220p' || true

echo
echo "== trivyignore files =="
git ls-files | grep -E '(^|/)\.trivyignore$' || true

echo
echo "== changed/files context around .github/workflows/trivy.yml =="
git status --short

Repository: constructorfabric/insight-front

Length of output: 411


🌐 Web query:

Trivy ignorefile default path docker run --ignorefile .trivyignore ./ --ignorefile .trivyignore documentation

💡 Result:

The default path for the Trivy ignore file is.trivyignore [1][2][3]. When running Trivy in a Docker container, you must ensure the ignore file is accessible to the containerized Trivy process. You can use the --ignorefile flag to specify a custom path, but because Trivy runs inside a container, you must mount the local ignore file into the container using the -v (volume) flag [4]. If you have a file named.trivyignore in your current local directory and wish to use it when scanning, you can run: docker run --rm -v /var/run/docker.sock:/var/run/docker.sock -v $(pwd)/.trivyignore:/.trivyignore aquasec/trivy image --ignorefile /.trivyignore [TARGET_IMAGE] In this command: 1. -v $(pwd)/.trivyignore:/.trivyignore: Mounts your local.trivyignore file to a path inside the container (e.g., the root directory). 2. --ignorefile /.trivyignore: Tells the Trivy process inside the container to look at the mounted file for ignore rules. If you do not specify a path with the --ignorefile flag, Trivy defaults to looking for a file named.trivyignore in its current working directory within the container [2][3].

Citations:


🌐 Web query:

Trivy CLI ignore file default location --ignorefile current working directory target path

💡 Result:

Trivy automatically checks for a file named.trivyignore in your current working directory by default [1]. If this file exists, Trivy will load it without requiring any additional configuration [1]. Key points regarding the ignore file: 1. Default Behavior: Trivy is configured to look for.trivyignore in the directory where the command is executed [2][3][1]. 2. Using --ignorefile: You can explicitly specify a different file or path using the --ignorefile flag (e.g., trivy image --ignorefile path/to/custom-ignore-file my-image:latest) [3][4][1]. 3. Validation: If you use the --ignorefile flag to specify a path, Trivy will verify that the file exists [5]. If the file cannot be found, Trivy will return an error [5][6]. 4. Supported Formats: While the default.trivyignore file is standard, Trivy also supports experimental YAML-based ignore files (e.g.,.trivyignore.yaml), which must be explicitly specified via the --ignorefile flag [7]. You do not need to provide any arguments for Trivy to utilize the.trivyignore file located in your current working directory; it is the default location [2][8][1].

Citations:


🌐 Web query:

site:trivy.dev docs ignorefile .trivyignore default path current working directory

💡 Result:

By default, Trivy looks for an.trivyignore file in the current working directory [1][2][3]. The --ignorefile flag is used to specify the path to an ignore file if it is located elsewhere or has a different name [1][4]. Additionally, you can configure the path to the ignore file within a Trivy configuration file (typically trivy.yaml) by setting the ignorefile parameter [1][5].

Citations:


Point the .trivyignore waiver file into the Trivy cwd.

By default Trivy loads .trivyignore from the container’s current working directory, so a workspace-root waiver remains outside the scan process unless the container cwd is set to /src or --ignorefile /src/.trivyignore is passed.

🔧 Proposed fix
       - name: Trivy fs scan — CRITICAL only (blocking)
         run: |
           docker run --rm \
             -v "${{ github.workspace }}:/src:ro" \
+            -w /src \
             "$TRIVY_IMAGE" fs \
               --scanners vuln,secret,misconfig \
               --severity CRITICAL \
               --ignore-unfixed \
+              --ignorefile /src/.trivyignore \
               --exit-code 1 \
               --no-progress \
               /src
📝 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
- name: Trivy fs scan — CRITICAL only (blocking)
# `--ignore-unfixed` keeps the gate actionable: a CRITICAL with no released fix cannot
# be resolved by the PR author, so it belongs in the report pass, not in a merge block.
# Waivers go in `.trivyignore` at the repo root, date-scoped:
# CVE-2026-12345 exp:2026-12-31 # tracked in <issue>, fix queued
run: |
docker run --rm \
-v "${{ github.workspace }}:/src:ro" \
"$TRIVY_IMAGE" fs \
--scanners vuln,secret,misconfig \
--severity CRITICAL \
--ignore-unfixed \
--exit-code 1 \
--no-progress \
/src
- name: Trivy fs scan — CRITICAL only (blocking)
# `--ignore-unfixed` keeps the gate actionable: a CRITICAL with no released fix cannot
# be resolved by the PR author, so it belongs in the report pass, not in a merge block.
# Waivers go in `.trivyignore` at the repo root, date-scoped:
# CVE-2026-12345 exp:2026-12-31 # tracked in <issue>, fix queued
run: |
docker run --rm \
-v "${{ github.workspace }}:/src:ro" \
-w /src \
"$TRIVY_IMAGE" fs \
--scanners vuln,secret,misconfig \
--severity CRITICAL \
--ignore-unfixed \
--ignorefile /src/.trivyignore \
--exit-code 1 \
--no-progress \
/src
🤖 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/trivy.yml around lines 57 - 71, Update the Trivy
invocation in the “Trivy fs scan — CRITICAL only (blocking)” workflow step to
explicitly load the workspace-root waiver file by passing /src/.trivyignore via
Trivy’s ignorefile option, preserving the existing scan behavior and options.

Comment on lines +105 to +106
"file": git.get("file") or "?",
"line": git.get("line") or "",

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

Do not emit repository paths verbatim in the summary.

Line 119 writes an untrusted filename directly to GITHUB_STEP_SUMMARY. A finding in a path containing a credential can disclose that value despite the redaction policy; path characters can also alter the Markdown table. Report only detector and commit, and inspect the commit locally for the exact location.

Proposed fix
-                      "file": git.get("file") or "?",
-                      "line": git.get("line") or "",
...
-          w("| Detector | Verified | Commit | Path |\n|---|---|---|---|\n")
+          w("| Detector | Verified | Commit |\n|---|---|---|\n")
           for r in sorted(rows, key=lambda r: (not r["verified"], r["detector"])):
-              w(f"| `{r['detector']}` | {'yes' if r['verified'] else 'no'} | `{r['commit']}` | `{r['file']}`{':' + str(r['line']) if r['line'] else ''} |\n")
+              w(f"| `{r['detector']}` | {'yes' if r['verified'] else 'no'} | `{r['commit']}` |\n")

Also applies to: 117-119

🤖 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/trufflehog.yml around lines 105 - 106, Update the
TruffleHog summary generation around the `git.get("file")` and `git.get("line")`
fields so repository paths and line values are not emitted to
`GITHUB_STEP_SUMMARY`; report only the detector and commit fields, while
retaining local inspection of the commit for the exact finding location.

docker.yml conflicted: #227 (branch-tagged image builds) added a
"Report pushed image" step at the end of the merge job, exactly where this
branch appends the trivy-image job. Both kept — the step stays inside merge,
trivy-image follows as a separate job.

trivy-image's gating comment was stale after #227: it justified the main-only
condition by metadata-action's enable={{is_default_branch}}, which #227 removed
so branch dispatches now push a tagged image too. The condition is unchanged
(main-only, matching the promotion path it guards); the comment now says why and
how to widen it. needs.merge.outputs.build_tag still resolves — merge forwards
prepare's branch-suffixed tag.

Signed-off-by: Konstantin Tursunov <konstantin.tursunov@constructor.tech>

@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: 2

🤖 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/workflows/docker.yml:
- Around line 215-217: Add a second vulnerability-scan pass for the published
image in the workflow, explicitly setting --platform linux/arm64 and retaining
the existing scan options. Upload the arm64 results to Code Scanning with a
distinct SARIF category from the amd64 scan, while preserving the current amd64
pass.
- Around line 231-249: Update both Trivy image scan commands in the Docker
workflow to include the --scanners vuln option, ensuring the terminal table and
trivy-image.sarif contain vulnerability findings only while preserving their
existing severity, output, and exit-code settings.
🪄 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: 750e3a3b-2edd-4cba-b81c-79ad77f61a43

📥 Commits

Reviewing files that changed from the base of the PR and between c7ddade and 31ab007.

📒 Files selected for processing (6)
  • .github/workflows/docker.yml
  • .github/workflows/semgrep.yml
  • .github/workflows/trivy.yml
  • .github/workflows/trufflehog.yml
  • .gitignore
  • .semgrepignore
🚧 Files skipped from review as they are similar to previous changes (5)
  • .semgrepignore
  • .gitignore
  • .github/workflows/trufflehog.yml
  • .github/workflows/trivy.yml
  • .github/workflows/semgrep.yml

Comment on lines +215 to +217
# `--ignore-unfixed` keeps the output to what a base-image bump can actually fix.
# A multi-arch manifest resolves to the runner's platform (linux/amd64); the arm64
# leg shares the same base image and package set, so one pass is representative.

@coderabbitai coderabbitai Bot Jul 29, 2026

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

echo "== workflow context =="
if [ -f .github/workflows/docker.yml ]; then
  nl -ba .github/workflows/docker.yml | sed -n '180,250p'
else
  echo "missing .github/workflows/docker.yml"
fi

echo
echo "== trivy invocations in docker workflow =="
rg -n "trivy|sarif|platform|scan" .github/workflows/docker.yml || true

echo
echo "== workflow files =="
git ls-files '.github/workflows/*'

Repository: constructorfabric/insight-front

Length of output: 232


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== workflow context =="
if [ -f .github/workflows/docker.yml ]; then
  awk '{printf "%6d  %s\n", NR, $0}' .github/workflows/docker.yml | sed -n '180,250p'
else
  echo "missing .github/workflows/docker.yml"
fi

echo
echo "== trivy invocations in docker workflow =="
grep -nE "trivy|sarif|platform|scan|multi-arch|manifest|docker manifest|linux/amd64|linux/arm64" .github/workflows/docker.yml || true

echo
echo "== workflow files =="
git ls-files '.github/workflows/*'

Repository: constructorfabric/insight-front

Length of output: 6385


🌐 Web query:

Trivy container image scan multi-platform image default platform --platform documentation

💡 Result:

In Trivy, the --platform flag is used to specify the operating system and architecture (in the format os/architecture) for scanning multi-platform container images [1][2]. Regarding the default behavior and the --platform flag: - Default Behavior: When the --platform flag is not specified, Trivy attempts to load the image based on the platform of the host machine where Trivy is running [1][3]. For example, on a linux/amd64 host, Trivy defaults to scanning the linux/amd64 version of a multi-arch image [1][3]. - Using --platform: If you need to scan a specific architecture or OS variant, you can use the --platform argument to explicitly set the desired platform [1][3]. For example: trivy image --platform=linux/arm64 [YOUR_IMAGE_NAME] Additional Considerations: - Compatibility: The --platform flag is primarily intended for multi-platform images. If you specify a platform that does not exist within the image's manifest, the scan result may depend on how the underlying registry or container engine handles the request, as Trivy aims to mimic the behavior of standard container tools like Docker [4][5]. - Local vs. Remote: When scanning local images (e.g., from Docker Engine), Trivy relies on the container engine to provide the image content [3][6]. When scanning remote images, Trivy interacts directly with the registry, which can sometimes lead to differing behaviors compared to local scanning if platform auto-detection is not aligned [6]. - Configuration: You can also set this parameter in the Trivy configuration file using the image.platform key [7].

Citations:


🌐 Web query:

GitHub Code Scanning SARIF upload max 5 results upload-sarif multiple SARIF files

💡 Result:

GitHub Code Scanning supports uploading multiple SARIF files for a single commit [1][2]. To upload multiple files, you must ensure each file represents a unique set of results by assigning each a unique "category" [1][3]. By default, code scanning expects one SARIF file per analysis; uploading a second file for the same category and tool will overwrite the previous results [1][4]. If you attempt to upload multiple files for the same tool and category within a single GitHub Actions workflow run, the configuration is considered invalid, and the run will fail [1][3]. Key details for managing multiple SARIF files: - The upload-sarif action's sarif_file input accepts both a single file path and a directory path [1][5]. When a directory is provided, the action recursively searches for and uploads all files ending in.sarif [6]. - Each SARIF file in a directory upload must be identified as a unique set, often by ensuring each file contains a unique runAutomationDetails.id if a category is not explicitly provided [4][3]. - While SARIF supports multiple files, GitHub imposes strict limits on the data contained within those files [7][8]. For example, a single run can contain a maximum of 25,000 results, with only the top 5,000 results displayed [7][8]. If a file exceeds these thresholds, it may be rejected or truncated [7][8]. The "5 results" limit mentioned in your query does not exist as a global hard limit for uploads, though specific data objects within the SARIF structure are subject to various hard and soft limits (e.g., maximum results per run, maximum locations per result) [7][9][8].

Citations:


Scan the published arm64 image as well.

The workflow builds linux/amd64 and linux/arm64, but this check resolves the tag from the runner and scans only amd64. Add an explicit arm64 pass with --platform linux/arm64 and upload it under a distinct SARIF category so both image architectures are covered by Code Scanning.

🤖 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/docker.yml around lines 215 - 217, Add a second
vulnerability-scan pass for the published image in the workflow, explicitly
setting --platform linux/arm64 and retaining the existing scan options. Upload
the arm64 results to Code Scanning with a distinct SARIF category from the amd64
scan, while preserving the current amd64 pass.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

not required, publishing only amd64

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@ktursunov, the current workflow appears to publish both architectures: the build matrix pushes linux/amd64 and linux/arm64, and merge assembles them into one multi-arch manifest. As written, the scan covers only the amd64 variant.

If arm64 publication is no longer intended, removing the arm64 matrix leg would make this finding inapplicable; otherwise, the separate arm64 scan remains relevant.

Comment on lines +231 to +249
"$TRIVY_IMAGE" image \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format table \
"$IMAGE_REF"
docker run --rm \
-v "${{ github.workspace }}:/work" \
-v /tmp/trivy-cache:/root/.cache \
-e TRIVY_USERNAME -e TRIVY_PASSWORD \
"$TRIVY_IMAGE" image \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format sarif --output /work/trivy-image.sarif \

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

echo "== workflow excerpt =="
if [ -f .github/workflows/docker.yml ]; then
  sed -n '200,270p' .github/workflows/docker.yml | cat -n
else
  echo ".github/workflows/docker.yml not found"
fi

echo
echo "== trivy references in workflow =="
rg -n "trivy|TRIVY|scanners|sarif|secret" .github/workflows/docker.yml || true

echo
echo "== related PR/workflow files =="
git ls-files '.github/workflows/*' . | sed -n '1,120p'

Repository: constructorfabric/insight-front

Length of output: 9673


🌐 Web query:

Trivy v0.72 image --scanners default vuln secret SARIF output

💡 Result:

To generate a SARIF report for an image scan using Trivy v0.72, you can use the built-in --format sarif flag [1][2][3]. Since vulnerability (vuln) and secret (secret) scanning are enabled by default for container image scans [4][5][6], you do not need to explicitly specify them unless you wish to limit the scope of the scan [5][7]. The command syntax is as follows: trivy image --format sarif --output report.sarif [IMAGE_NAME] Explanation of flags: --format sarif: Sets the output format to SARIF (Static Analysis Results Interchange Format) [1][2][3]. --output report.sarif: Specifies the file path where the report should be saved [2][3][8]. --scanners [vuln,secret]: These are enabled by default, so omitting them defaults to running both [4][5]. If you want to explicitly ensure both are included, you can append --scanners vuln,secret to the command [4][1]. Note: Earlier versions of Trivy occasionally required the use of --template for SARIF generation, but modern versions (including v0.72) support --format sarif natively [1][2][3].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== trivy workflow excerpt =="
if [ -f .github/workflows/trivy.yml ]; then
  sed -n '1,240p' .github/workflows/trivy.yml | cat -n
else
  echo ".github/workflows/trivy.yml not found"
fi

echo
echo "== secret scanner references across workflows =="
rg -n "trivy|upload-sarif|secrets|secret|scanners|SARIF" .github/workflows/trivy.yml .github/workflows/docker.yml .github/workflows/semgrep.yml .github/workflows/trufflehog.yml || true

Repository: constructorfabric/insight-front

Length of output: 15552


Vulnerability-only image scans here.

Trivy image scans default to vuln,secret, so both the terminal table and the uploaded trivy-image.sarif can include secret findings even though secret detection is owned by the TruffleHog workflow. Add --scanners vuln to both image commands to keep this SARIF pass aligned with the vulnerability-only reporting contract.

Proposed fix
             "$TRIVY_IMAGE" image \
+              --scanners vuln \
               --severity CRITICAL,HIGH \
@@
             "$TRIVY_IMAGE" image \
+              --scanners vuln \
               --severity CRITICAL,HIGH \
📝 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
"$TRIVY_IMAGE" image \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format table \
"$IMAGE_REF"
docker run --rm \
-v "${{ github.workspace }}:/work" \
-v /tmp/trivy-cache:/root/.cache \
-e TRIVY_USERNAME -e TRIVY_PASSWORD \
"$TRIVY_IMAGE" image \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format sarif --output /work/trivy-image.sarif \
"$TRIVY_IMAGE" image \
--scanners vuln \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format table \
"$IMAGE_REF"
docker run --rm \
-v "${{ github.workspace }}:/work" \
-v /tmp/trivy-cache:/root/.cache \
-e TRIVY_USERNAME -e TRIVY_PASSWORD \
"$TRIVY_IMAGE" image \
--scanners vuln \
--severity CRITICAL,HIGH \
--pkg-types os,library \
--ignore-unfixed \
--exit-code 0 \
--no-progress \
--format sarif --output /work/trivy-image.sarif \
🤖 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/docker.yml around lines 231 - 249, Update both Trivy image
scan commands in the Docker workflow to include the --scanners vuln option,
ensuring the terminal table and trivy-image.sarif contain vulnerability findings
only while preserving their existing severity, output, and exit-code settings.

@ktursunov
ktursunov merged commit 727d917 into main Jul 29, 2026
12 checks passed
@ktursunov
ktursunov deleted the ci/security-gates-sast-sca-secrets branch July 30, 2026 13:00
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.

3 participants