Skip to content

ci(security): Trivy correctness fixes and a complete-coverage report - #230

Merged
Gregory91G merged 4 commits into
mainfrom
ci/trivy-ignorefile-and-single-scan
Jul 29, 2026
Merged

ci(security): Trivy correctness fixes and a complete-coverage report#230
Gregory91G merged 4 commits into
mainfrom
ci/trivy-ignorefile-and-single-scan

Conversation

@Gregory91G

@Gregory91G Gregory91G commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Ports three review findings from constructorfabric/insight#2002 to this repo, so the two scanning setups do not drift apart. No behaviour change to what is reported — only to what is honored, what is logged on failure, and how many times Trivy runs.

1. The repo-root .trivyignore was never read

trivy.yml documents that waivers go in a date-scoped .trivyignore at the repo root. They did not work. Trivy resolves the default ignore file relative to the working directory, and the containers set no -w, so the file was looked for in the Trivy image's own cwd rather than in the mounted tree.

Measured on a minimal tree (a Dockerfile with no USER, so DS-0002 HIGH):

Command exit
no .trivyignore 1 — finding reported
.trivyignore with DS-0002 at the root, command as it was 1 — waiver ignored
same plus -w /src 0 — waiver honored
same plus --ignorefile /src/.trivyignore 0 — waiver honored

Fixed with -w, not --ignorefile: Trivy exits FATAL ignore file not found when the named file is absent, and neither repo has a .trivyignore yet, so that variant would break every run until someone added a waiver. Verified both ways — with a waiver present the gate now honors it, and with no .trivyignore at all the gate is unaffected.

Impact today is latent: there are no waivers to honor. But the first person whom the gate blocks on an unfixable CRITICAL would follow the documented instruction and find it does nothing.

2. SARIF upload ran even when no SARIF existed

The upload steps used if: always() against files that a failed scan never writes. When a scan step dies (registry auth, network, DB download), the job is already red — and then upload-sarif adds a second error about a missing path, which points at Code Scanning instead of the scan that actually broke. A hashFiles(...) != '' guard drops that, keeping the fork-PR condition intact.

3. Trivy scanned twice to produce two formats

Both passes ran the full scan twice over an identical target: the repository pass for SARIF and JSON, the image scan for a log table and SARIF. trivy convert derives every other format from a saved JSON report without rescanning.

Now: one scan → JSON, then convert for the rest. Output is byte-for-byte equivalent in count — verified against what main currently reports:

Pass Before After (via convert)
repository (trivy-fs) 31 results 31
image (trivy-image) 37 results 37

The image scan gains the most: it drops a second registry pull and a second layer analysis per run.

Test plan

Run locally against this branch.

  • YAML parses for all six workflows
  • actionlint on both changed files — no new findings (the two pre-existing SC2046/SC2016 warnings on Create multi-arch manifest and Report pushed image are untouched)
  • Gate with -w /src against this repository — exit 0, still green
  • Waiver honored: .trivyignore with DS-0002 now suppresses the finding, where the previous command reported it
  • Gate unaffected when no .trivyignore exists — the current state of the repo
  • Repository pass: one scan → JSON (29 vulnerabilities + 2 misconfigurations), convert → SARIF with 31 results, matching main
  • Image pass against the real published image ghcr.io/constructorfabric/insight-front:latest — one scan → JSON, convert --format table renders Total: 37 (HIGH: 35, CRITICAL: 2), convert --format sarif yields 37 results, matching main
  • The trivy-image job itself — runs on push to main, so first exercised after merge

Summary by CodeRabbit

  • Bug Fixes
    • Improved reliability of vulnerability scanning and SARIF generation by producing reports in a single pass and converting formats consistently.
    • Avoided empty or failed SARIF uploads when expected output is missing.
  • New Features
    • Added additional secret scanning for non–pull request events using a GitHub-API-based approach.
  • CI Behavior Updates
    • Updated SCA/SAST workflows so critical findings are report-only (no longer blocking), and added a push-to-main trigger to ensure timely baseline scanning.

Part 2 — completeness of the report

The three fixes above are correctness. This second commit is about coverage: what the scans
report, not what they block. No behaviour of any gate changes and nothing is fixed — fixing
the findings is separate work.

Four gaps, each measured on this repository before being closed:

Gap Was Now
The report pass filtered to HIGH/MEDIUM/LOW while the gate that covers CRITICAL only prints a table — so a CRITICAL failed the check and never became an alert CRITICAL invisible in Code Scanning CRITICAL included in the report severities
Dev dependencies excluded by Trivy's pnpm default. They do not ship, but a compromised one runs on the runner and can alter the bundle 29 vulnerabilities 37
Image scan filtered to CRITICAL/HIGH 37 findings 107 — the narrow filter hid 70
Secrets scanned only through git refs comments, wikis and orphaned objects unscanned new report-only job on the GitHub API source: ~8600 chunks vs the git scan's ~6900, 10 seconds

semgrep.yml also gains a push: main trigger. Without it Code Scanning holds no SAST data for
the default branch between a merge and the 03:27 nightly, so a merge that introduces a finding is
invisible until the next morning — and the front's branch:main filter currently shows Trivy only.

Deliberately not added

  • Extra Semgrep rule packs (p/javascript, p/typescript, p/react, p/owasp-top-ten).
    Measured: rules 525 → 564, findings 19 → 20, and the one extra is not in src/.
    --config auto already selects what matters for this codebase.
  • Lock files, image-scan-at-publish, Helm chart rendering — the other candidates from the
    same review. None apply here: this repo already has pnpm-lock.yaml, already scans its image at
    publish time, and holds no Helm chart (the frontend chart lives in constructorfabric/insight
    under src/frontend/helm).

What the report will contain after this merges

Roughly 146 Trivy alerts on main — 39 from the repository (37 vulnerabilities + 2
misconfigurations) and 107 from the image — plus the Semgrep baseline that the new push trigger
produces immediately instead of overnight. Before this PR: 68.

Test plan — part 2

  • YAML parses for all six workflows
  • actionlint on all four changed files — no new findings
  • Repository pass with the widened severity list and --include-dev-deps — 37 vulnerabilities + 2 misconfigurations, up from 29 + 2
  • Image pass against the real published image — 107 findings (2 CRITICAL / 35 HIGH / 44 MEDIUM / 26 LOW), up from 37
  • --ignore-unfixed verified to make no difference on the current image: all 107 have a published fix
  • GitHub API secret scan run for real against this repository — 8608 chunks, 0 findings, 10 seconds
  • New summary script extracted verbatim from the YAML and run against that real output, and against a non-empty control set — renders redacted, exits 0 in both cases (report-only)
  • Secret gate over this PR's own range — 0 findings

Closes constructorfabric/insight#2079

…once

Ports three review findings from constructorfabric/insight#2002 to this repo, so
the two scanning setups do not drift.

The repo-root `.trivyignore` documented on the gate job was never read. Trivy
resolves the default ignore file relative to the working directory, and the
containers had no `-w`, so waivers were looked for in the image's own cwd.
Verified: with a waiver present the gate now honors it where it previously did
not, and with no `.trivyignore` at all — the current state of this repo — the
gate is unaffected. `--ignorefile` is deliberately not used: Trivy exits FATAL
when the named file is absent, which would break every run until someone adds a
waiver.

SARIF upload steps ran under `always()` against files a failed scan never wrote,
producing a second error pointing at Code Scanning instead of the scan that
actually broke. A `hashFiles` guard drops that.

Both report passes scanned the same target twice to produce two formats. The scan
now runs once to JSON and `trivy convert` derives the rest — SARIF for the
repository pass, and both the log table and SARIF for the image scan. Output is
identical: 31 results for the repository pass and 37 for the image, matching what
main currently reports.

Signed-off-by: Grigoriy Gogin <Grigoriy.Gogin@constructor.tech>
@Gregory91G
Gregory91G requested a review from a team as a code owner July 29, 2026 07:37
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Trivy image and filesystem scans now generate JSON reports for table and SARIF conversion, with report-only critical findings and guarded SARIF uploads. TruffleHog reports findings without failing jobs and adds GitHub API scanning. Semgrep now runs on pushes to main.

Changes

Security workflow changes

Layer / File(s) Summary
Filesystem scan and reporting
.github/workflows/trivy.yml
The Trivy gate is report-only; the report scan includes all severities and development dependencies, converts JSON to SARIF, updates severity summaries, and checks SARIF existence before upload.
Image scan and reporting
.github/workflows/docker.yml
The image job performs one JSON scan, derives table and SARIF outputs with trivy convert, uses /work as its working directory, and checks for SARIF existence before upload.
Secret scan reporting
.github/workflows/trufflehog.yml
TruffleHog findings no longer fail the workflow, and non-pull-request events run an additional GitHub API scan with redacted summaries.
Semgrep baseline trigger
.github/workflows/semgrep.yml
Semgrep now runs on pushes to the main branch in addition to existing triggers.

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

Possibly related PRs

Suggested reviewers: ktursunov, aleksdotbar

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
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.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main Trivy/reporting focus of the PR and is specific enough for history scanning.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ci/trivy-ignorefile-and-single-scan

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.

…objects

Widens what the scans report. Nothing here changes what blocks a merge, and no
finding is fixed — this is about the report being complete.

Four gaps, each measured on this repository:

  - The repository report pass filtered to HIGH/MEDIUM/LOW while the gate, which
    covers CRITICAL, only prints a table. A CRITICAL therefore failed the check
    and never became an alert. CRITICAL is now in the report severities too;
    reporting and blocking are separate concerns.
  - Dev dependencies were excluded by Trivy's pnpm default. They do not ship, but
    a compromised one executes on the runner and can alter the bundle. Including
    them takes the repository pass from 29 to 37 vulnerabilities.
  - The image scan filtered to CRITICAL/HIGH, hiding 70 of 107 findings in the
    image that actually ships.
  - Secrets were only scanned through git refs. A new report-only job uses the
    GitHub API source, which additionally sees pull request and issue comments,
    wikis, and objects orphaned by a force push or a deleted branch — all
    unreachable from any ref and therefore invisible to the git scan. Measured:
    ~8600 chunks against the git scan's ~6900, ten seconds. Off pull requests and
    non-blocking, since it depends on API availability.

semgrep.yml gains a push trigger for main. Without it Code Scanning holds no SAST
data for the default branch between a merge and the 03:27 nightly run, so a merge
that introduces a finding stays invisible until the next morning.

Deliberately not added: extra Semgrep rule packs (p/javascript, p/typescript,
p/react, p/owasp-top-ten). Measured on this repository they raise the rule count
from 525 to 564 and the finding count from 19 to 20 — `--config auto` already
selects what matters here.

Signed-off-by: Grigoriy Gogin <Grigoriy.Gogin@constructor.tech>
@Gregory91G Gregory91G changed the title ci(security): honor repo-root .trivyignore, guard SARIF upload, scan once ci(security): Trivy correctness fixes and a complete-coverage report Jul 29, 2026
Every scan here becomes observational. Two checks blocked until now: the Trivy
CRITICAL pass and the TruffleHog history scan. Both keep running, keep reporting,
and stop deciding whether a branch can merge.

  - Trivy: `--exit-code 1` becomes `--exit-code 0`. The pass is renamed from
    `gate (CRITICAL)` to `critical (report-only)` — a check named "gate" that
    gates nothing is worse than no check at all.
  - TruffleHog: the summary step no longer exits non-zero on a finding. It still
    renders the redacted table and still says to rotate.

Comments follow the behaviour: nothing in either file claims to block any more,
and where a waiver mechanism only matters under enforcement, the comment says so.

Baselines are unchanged by this: 0 CRITICAL and 0 secrets. Nothing was passing
because of these gates, so nothing regresses by removing them — what changes is
that a future finding will be reported rather than enforced.

Turning enforcement back on is prepared separately and deliberately not merged.

Refs #231

Signed-off-by: Grigoriy Gogin <Grigoriy.Gogin@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/trivy.yml (1)

120-124: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Generate the trivy convert table report in the report job.

The report step still only converts the JSON to SARIF. Add the same convert --format table step used by .github/workflows/docker.yml so the job log includes Trivy’s table report rather than only the Python summary.

🤖 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 120 - 124, Update the Trivy
conversion commands in the report job of trivy.yml to also run convert with
--format table, matching the established step in docker.yml. Keep the existing
SARIF conversion and Python summary, and ensure the table output is emitted to
the job log.

Source: MCP tools

🤖 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/trivy.yml:
- Around line 114-115: Update the Trivy workflow command to include UNKNOWN in
the --severity list, and update the later summary’s severity counts and ranking
to include UNKNOWN as well. Keep the scan and summary severity sets consistent
so undetermined-severity findings are reported end to end.

In @.github/workflows/trufflehog.yml:
- Around line 143-160: Update the TruffleHog workflow’s GitHub API scan at
.github/workflows/trufflehog.yml lines 143-160 to either invoke
github-experimental with --object-discovery and an appropriately longer timeout
for unreachable-object coverage, or remove unreachable-object claims and scope
the scan summary accordingly; also update the related summary at
.github/workflows/trufflehog.yml lines 199-201 to match the chosen coverage.
Preserve the existing reachable API scans and findings output.

---

Outside diff comments:
In @.github/workflows/trivy.yml:
- Around line 120-124: Update the Trivy conversion commands in the report job of
trivy.yml to also run convert with --format table, matching the established step
in docker.yml. Keep the existing SARIF conversion and Python summary, and ensure
the table output is emitted to the job log.
🪄 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: b475561e-2560-41e1-9ad2-562c190dd984

📥 Commits

Reviewing files that changed from the base of the PR and between cd7214d and 7f73828.

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

Comment on lines +114 to +115
--severity CRITICAL,HIGH,MEDIUM,LOW \
--include-dev-deps \

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 "Locate workflow files"
fd -a 'trivy\.yml$|trivy\.yaml$' .github/workflows 2>/dev/null || true

echo
echo "Relevant workflow excerpt"
if [ -f .github/workflows/trivy.yml ]; then
  nl -ba .github/workflows/trivy.yml | sed -n '90,180p'
else
  echo ".github/workflows/trivy.yml not found"
fi

echo
echo "Search for UNKNOWN and trivy severity/reporting"
rg -n "unknown|UNKNOWN|trivy" .github/workflows/trivy.yml .github/workflows -S || true

Repository: constructorfabric/insight-front

Length of output: 306


🏁 Script executed:

#!/bin/bash
set -u

echo "Workflow excerpt"
awk 'NR>=90 && NR<=180 { printf "%6d\t%s\n", NR, $0 }' .github/workflows/trivy.yml

echo
echo "Search for UNKNOWN and relevant reporting lines"
grep -n "unknown\|UNKNOWN\|--severity\|for s in\|rank\|every severity" .github/workflows/trivy.yml .github/workflows -S || true

Repository: constructorfabric/insight-front

Length of output: 5971


🌐 Web query:

Trivy --severity UNKNOWN documentation

💡 Result:

In Trivy, the UNKNOWN severity signifies that a vulnerability's severity rating could not be determined from the available data sources [1][2]. Key aspects regarding the UNKNOWN severity include: Severity Assignment Logic: Trivy automatically aggregates severity data from multiple sources (such as NVD, GHSA, and OS-specific vendors) to provide the most accurate assessment [1][3]. If no configured vendor or data source provides a severity rating for a vulnerability, Trivy defaults to UNKNOWN [1][2]. Customizing Severity Sources: Users can control how severities are determined using the --vuln-severity-source flag [1][4]. This allows you to specify a priority list of data sources [4]. Trivy will check these sources in the order provided; if none of the specified sources contain a severity, it will fall back to UNKNOWN [1][4]. For example: --vuln-severity-source nvd,ghsa: Trivy checks NVD first, then GHSA, and returns UNKNOWN if neither provides a severity [4]. Reasons for UNKNOWN Severity: - Data Delay: Some vendors (like NVD) may delay severity analysis for new vulnerabilities, while others may provide it more quickly [1][5]. - Missing Detail: Vulnerabilities detected via OS advisories (e.g., Alpine secdb) may lack severity information in the underlying vulnerability database if the detail entry has not yet been populated [6]. - Light Database Mode: Using the --light option may result in UNKNOWN severities because the lightweight database lacks detailed vulnerability information (such as CVSS scores) often used to calculate severity [7]. Trivy Severity Mapping: In Trivy's internal classification, UNKNOWN is mapped to the value 0, while others are assigned as follows [1][2]: 0: Unknown 1: Low 2: Medium 3: High 4: Critical

Citations:


🌐 Web query:

Trivy UNKNOWN severity documentation

💡 Result:

In Trivy, the "UNKNOWN" severity indicates that a vulnerability's severity level could not be determined from any of the available data sources (such as NVD, GHSA, or vendor-specific databases) [1][2][3]. Key points regarding the UNKNOWN severity: Determination Logic: Trivy automatically attempts to assign a severity based on a prioritized list of sources [1][2][4]. If no vendor or data source provides a specific severity rating, and it cannot be calculated via a CVSS score, Trivy assigns it the UNKNOWN severity [1][3]. Avoiding UNKNOWNs: To minimize the occurrence of UNKNOWN severities, Trivy is designed to use severity ratings from various vendors as fallbacks. For example, even if an NVD severity is not yet available, Trivy may use severity data from other vendors (like Red Hat) to provide a more actionable assessment [1][3][5]. Customization: Users can influence how severity is determined using the --vuln-severity-source flag [1][2][6]. This allows you to define a custom order of priority for severity sources. If you specify a sequence of sources, Trivy will check them in that order; if none of the specified sources contain a severity, Trivy will result in an UNKNOWN severity [1][2][6]. Reporting: In the context of reporting, UNKNOWN is considered a severity level (mapped to numerical value 0), distinct from other levels like Low, Medium, High, and Critical [1][2][3]. It is also important to distinguish this from vulnerability "status" (e.g., "unknown" status), which refers to whether a package is affected by a vulnerability on a specific platform [7]. For technical verification, you can check the SeveritySource field in Trivy's JSON output to identify exactly which source provided the severity (or if it was unable to be determined) for a specific vulnerability [2][3].

Citations:


Include Trivy’s UNKNOWN severity end to end.

--severity CRITICAL,HIGH,MEDIUM,LOW filters out UNKNOWN findings, while the summary later says it reports every severity. Add UNKNOWN to the scan and include it in the summary counts/ranking so vulnerabilities without a determined severity are not silently omitted.

🤖 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 114 - 115, Update the Trivy
workflow command to include UNKNOWN in the --severity list, and update the later
summary’s severity counts and ranking to include UNKNOWN as well. Keep the scan
and summary severity sets consistent so undetermined-severity findings are
reported end to end.

Source: MCP tools

Comment on lines +143 to +160
- name: TruffleHog scan (GitHub API — comments, wikis, unreachable objects)
env:
# The auto-injected token is enough for a public repository's commits and comments.
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
set -euo pipefail
docker run --rm \
-e GITHUB_TOKEN \
trufflesecurity/trufflehog:3.96.0@sha256:aa821cf4ace8861c7d096d83818cdf7bb9719028a52d37a52eaad44086a52577 \
github \
--repo "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}" \
--issue-comments \
--pr-comments \
--include-wikis \
--json \
--no-update \
--results=verified,unknown,unverified,filtered_unverified \
> trufflehog-api-findings.jsonl

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 | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

IMAGE='trufflesecurity/trufflehog:3.96.0@sha256:aa821cf4ace8861c7d096d83818cdf7bb9719028a52d37a52eaad44086a52577'

docker run --rm "$IMAGE" github --help
docker run --rm "$IMAGE" github-experimental --help

Repository: constructorfabric/insight-front

Length of output: 213


🌐 Web query:

TruffleHog 3.96.0 github github-experimental object-discovery documentation

💡 Result:

The github-experimental object-discovery module in TruffleHog is an alpha feature designed to identify Cross Fork Object References, allowing users to discover and scan hidden or deleted commits in GitHub repositories [1][2][3]. As of TruffleHog version 3.96.0, which was released on July 24, 2026 [4][5], this feature remains available via the following command structure: trufflehog github-experimental --repo https://github.com//.git --object-discovery Key details for using this feature include: Authentication: You must provide a valid GitHub Access Token, either by setting the GITHUB_TOKEN environment variable or by passing it via the --token flag [3]. Operational Behavior: When executed, TruffleHog creates two files in a $HOME/.trufflehog directory: valid_hidden.txt and invalid.txt [1][6]. The former contains a list of all discovered hidden and deleted commits [1][3]. Users can include the --delete-cached-data flag if they wish to have these files automatically removed after the scan is complete [1][2]. Performance: The enumeration process can be time-intensive, potentially taking from 20 minutes to several hours depending on the repository size, as it involves querying GitHub's services for commit hashes [1][3]. Configuration: The command supports a --collision-threshold flag (defaulting to 1), which allows users to manage the trade-off between scan speed and potential hash collisions [7][3][8]. For more context on the security implications of Cross Fork Object References, refer to the official Truffle Security blog [3][9].

Citations:


🌐 Web query:

site:github.com/marketplace/actions/trufflehog-oss TruffleHog GitHub experimental object discovery

💡 Result:

In TruffleHog, object discovery is an experimental sub-module within the github-experimental command designed to identify and scan hidden, deleted, or cross-fork commits in a GitHub repository [1]. To run this feature, use the command: trufflehog github-experimental --repo https://github.com//.git --object-discovery Key details about this experimental feature include: Data Outputs: When the --object-discovery flag is used, TruffleHog creates a $HOME/.trufflehog directory containing two files: valid_hidden.txt and invalid.txt [1]. These files track the state of commit enumeration and provide a list of all identified hidden and deleted commits [1]. Cleanup: To automatically remove these cached files after the scan completes, you can add the --delete-cached-data flag [1]. Performance: Enumerating all commits on a repository using this method can take between 20 minutes to several hours, depending on the repository size [1]. While enumeration takes time, the subsequent secret scanning phase is designed to run very quickly [1]. This functionality is categorized as an alpha release feature [1].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Workflow file info:\n'
wc -l .github/workflows/trufflehog.yml 2>/dev/null || true
sed -n '1,230p' .github/workflows/trufflehog.yml 2>/dev/null | nl -ba

printf '\nSearch for object discovery/github-experimental references:\n'
rg -n "github-experimental|object-discovery|object discovery|orphaned|unreachable|orphan|hidden" .github/workflows/trufflehog.yml . 2>/dev/null | head -120

Repository: constructorfabric/insight-front

Length of output: 266


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Workflow lines 1-230:\n'
python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/trufflehog.yml')
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    print(f"{i:4}: {line}")
PY

printf '\nSearch results:\n'
python3 - <<'PY'
import re
from pathlib import Path
terms = ('github-experimental', 'object-discovery', 'object discovery', 'orphaned', 'unreachable', 'orphan', 'hidden')
for path in sorted(Path('.').rglob('*')):
    if path.is_file() and '.git' not in path.parts:
        try:
            txt = path.read_text(errors='ignore').splitlines()
        except Exception:
            continue
        for idx, line in enumerate(txt, 1):
            if any(term in line for term in terms):
                print(f"{path}:{idx}:{line}")
PY

Repository: constructorfabric/insight-front

Length of output: 50388


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path('.github/workflows/trufflehog.yml')
text = p.read_text()
lines = text.splitlines()
for i, line in enumerate(lines, 1):
    if 1 <= i <= 80 or 130 <= i <= 210:
        print(f"{i:4}: {line}")
PY

Repository: constructorfabric/insight-front

Length of output: 8675


Align the GitHub API scan with TruffleHog execution realities.

The workflow notes unreachable objects live on the remote and need trufflehog github --repo, but this job uses trufflehog github for its claimed orphaned-object coverage. That also ignores TruffleHog’s github-experimental --object-discovery command for unreachable deleted/hidden commit enumeration; add that scan with a longer timeout if that coverage is required, or remove the unreachable-object language and scope the summary to reachable API content.

📍 Affects 1 file
  • .github/workflows/trufflehog.yml#L143-L160 (this comment)
  • .github/workflows/trufflehog.yml#L199-L201
🤖 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 143 - 160, Update the
TruffleHog workflow’s GitHub API scan at .github/workflows/trufflehog.yml lines
143-160 to either invoke github-experimental with --object-discovery and an
appropriately longer timeout for unreachable-object coverage, or remove
unreachable-object claims and scope the scan summary accordingly; also update
the related summary at .github/workflows/trufflehog.yml lines 199-201 to match
the chosen coverage. Preserve the existing reachable API scans and findings
output.

Review remark from @cyberantonz on constructorfabric/insight#2016, applied here
too since the same widening had landed in this workflow.

Measured before reverting: on a backend connector image the filter change takes
one image from 99 findings to 315, and across that estate from ~660 to ~2100. On
this repository's image it was 37 to 107.

The volume buys nothing. Every finding in an image comes from a base layer, and
the remedy is identical at every severity — refresh the base image. What the
wider filter does change is that the CRITICALs, which are the ones driving that
refresh, end up buried under three times as many MEDIUM and LOW entries.

Kept where it does pay: the repository pass stays at every severity. There the
volume is small (37 findings) and each one points at a dependency this repository
declares and can bump on its own.

Refs #231

Signed-off-by: Grigoriy Gogin <Grigoriy.Gogin@constructor.tech>
@Gregory91G
Gregory91G merged commit 6ff0d5a into main Jul 29, 2026
13 checks passed
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.

ci(security): complete vulnerability reporting (SCA, SAST, secrets, image)

2 participants