fix(security): notify only on finding-state-change + PR runs report-only (stop Telegram/Matrix spam) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/notify-state-change-pr-report-only"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The reusable
security.ymlandsecurity-hardened.ymlsend Telegram + Matrix on every run whereSECURITY_FINDINGS == 1(gated only by severity floor + channel filter). An unchanged finding set therefore re-spams chat on every push / PR / daily cron across ~50 thin-caller repos. The issue create/upsert/auto-close logic was already correct (stable<!-- security-scan:v2 -->marker, PATCH-in-place, auto-close on resolution) — the defect was purely on the notify side, pluspull_requestevents ran the full issue+chat pipeline.The 6 changes (applied to BOTH
security.ymlANDsecurity-hardened.yml)Finding-state fingerprint. In Build security report, after the findings are assembled, compute
SECURITY_FP = sha256of the sorted unique finding lines (CVE-id:packagerows from Trivy + a per-scanner section flag for node/pip/osv/misconfig/sast) and write it toGITHUB_ENV. Deterministic (sort -ubefore hashing).fp embedded in the issue marker. The marker becomes
<!-- security-scan:v2 fp=<SECURITY_FP> -->. In Create or update Forgejo security issue, the existing marker-issue is fetched once, its storedfpis parsed before patching, andCHANGED=1is set only if the issue is new OR the stored fp differs from the new fp (findings changed/escalated); elseCHANGED=0. The issue body is still PATCHed in place regardless so it stays current (new fp included). All marker-searchcontains(...)clauses were loosened from the exact<!-- security-scan:v2 -->to the prefix<!-- security-scan:v2so fp-marked issues still match (upsert + dedup + close).Notify gated on state-change. Both Notify Telegram and Notify Matrix now require
&& env.CHANGED == '1'. An unchanged finding set updates the issue silently and never re-pings chat.pull_requestruns are report-only. The issue-upsert step, both notify steps, and the close step now also carry&& github.event_name != 'pull_request'. PR runs scan + surface results in the run log only — no issues, no chat, no closes.Auto-close still works, notify once on resolution. The Close resolved... step counts how many issues it actually closes; when
>= 1, it emitsRESOLVED_NOTIFY=1and builds a single✅ Security findings resolvedmessage. Two new steps (Notify Telegram (resolved) / Notify Matrix (resolved)) send it once. When nothing was open, it stays silent (RESOLVED_NOTIFY=0).Example cron daily → weekly.
examples/security-caller.ymlcron changed from23 4 * * *to23 4 * * 1(Mondays) with a comment that push + PR already cover real changes — the weekly run is just a safety-net.README.mddocuments the new state-change-only notify behaviour, the fp marker, the resolve-once notify, and PR report-only. (The ~50 thin-caller repos are not edited here — the central reusable change already fixes notify for all of them; the cron is just the example default going forward.)Preserved / non-goals
All existing scanner functionality (Trivy fs vuln/secret[/misconfig/license], pip-audit, Node audit, OSV-Scanner, Hadolint, optional SAST), secrets usage (
MATRIX_*,TELEGRAM_*,GITHUB_TOKEN),SEC_NOTIFY_TARGETS,SEC_AUTO_CLOSE,notify_min_sevseverity floors, the anti-stampede jitter, and the overall YAML structure are untouched. The change is additive/surgical (security.yml: +124/-11, hardened: +124/-11; scanner steps not modified). Eachrun:block passesbash -n; all three YAML files parse cleanly.⚠️ Promotion required
Thin callers pin
@v2, which is a lightweight git tag, not a branch. Merging this PR tomainalone changes nothing fleet-wide — thev2tag must be re-pointed to the merged commit for the fix to take effect across all ~50 repos. Suggested promote steps (after review + merge tomain):(Repos pinned to
@mainpick it up immediately on next run;@v2repos only after the tag move.)🤖 Generated with Claude Code