checks/sast: detect Semgrep, Bandit, and gosec SAST workflows - #5103
Closed
DevamShah wants to merge 1 commit into
Closed
checks/sast: detect Semgrep, Bandit, and gosec SAST workflows#5103DevamShah wants to merge 1 commit into
DevamShah wants to merge 1 commit into
Conversation
Signed-off-by: Devam Shah <devamshah91@gmail.com>
DevamShah
requested review from
AdamKorcz and
spencerschrock
and removed request for
a team
June 23, 2026 01:36
yves-vogl
added a commit
to yves-vogl/moneymoney-paypal-pos-extension
that referenced
this pull request
Jun 23, 2026
- new .github/workflows/sast.yml runs Semgrep on push (main, phase-*) + PR (any) - ruleset: p/security-audit + p/secrets (D-34); --error makes ERROR-severity blocking (D-33) - SARIF upload via github/codeql-action/upload-sarif with if: always() so findings surface even on failure - pip install semgrep==1.167.0 (NOT container, avoids Docker Hub rate-limit per RESEARCH Pitfall 7) - SHA-pinned uses: actions/checkout@11bd719 (v4.2.2), actions/setup-python@a309ff8 (v6.2.0), github/codeql-action@8272c29 (v3.36.2) - top-level permissions: read-all; job permissions: security-events:write + actions:read + contents:read - checkout: persist-credentials: false + fetch-depth: 0 - job name 'Semgrep SAST' (load-bearing for Plan 06.1-04 branch-protection CHECKS array) - --exclude spec avoids JWT-shaped test fixtures (RESEARCH §5) - local dry-run (semgrep 1.167.0 against src/**) returned 0 findings, 0 suppressions needed Closes SEC-08 (the security control). Scorecard SAST score reporting deferred to upstream ossf/scorecard#5103 — ADR-0009 (Plan 06.1-08) documents the gap.
yves-vogl
added a commit
to yves-vogl/moneymoney-paypal-pos-extension
that referenced
this pull request
Jun 23, 2026
Add SUMMARY.md documenting the .github/workflows/sast.yml landing: - ruleset p/security-audit + p/secrets, ERROR-blocking, SARIF upload - SHA-pinned actions (checkout v4.2.2, setup-python v6.2.0, upload-sarif v3.36.2) - pip install semgrep==1.167.0 (not container) - local dry-run on src/** returned 0 findings, 0 suppressions - Scorecard SAST score gap documented (ossf/scorecard#5103 upstream pending) - branch-protection CHECKS update deferred to Plan 06.1-04 (deadlock prevention)
yves-vogl
added a commit
to yves-vogl/moneymoney-paypal-pos-extension
that referenced
this pull request
Jun 23, 2026
Documents the bewusst akzeptierten Gaps (Fuzzing 0/10, Code-Review 0/10, Packaging -1, Contributors structural, Maintained heals-itself) with compensating mitigations and Alternatives Considered (Option B 1-reviewer, Option C bot-reviewer, Snyk Code, SBOM+cosign+SLSA deferred to v1.1.x, G-09 awk shell-interpolation low-severity, Lua/CI Semgrep rulesets). Revises the Phase-6.1 aggregate target: ≥ 7.5 short-term, ≥ 8.5 once ossf/scorecard#5103 merges (SAST 0→10) AND repo age crosses 90 days (Maintained 0→8+, ~2026-09-15). Closes DOC-11 (in concert with this plan's SECURITY.md + REQUIREMENTS.md + ROADMAP.md edits).
yves-vogl
added a commit
to yves-vogl/moneymoney-paypal-pos-extension
that referenced
this pull request
Jun 23, 2026
- SEC-05 modified in-place: expanded with SCORECARD_READ_TOKEN provisioning, branch-protection invariants (linear history, no force-push/delete, no admin bypass), 5 required status checks, Scorecard Branch-Protection.score >= 3 (Tier 1; Option A locked per ADR-0009). - SEC-06 new: SHA-pinned uses: refs in workflows + CI grep gate + Dependabot lockstep + Scorecard Pinned-Dependencies.score == 10. - SEC-07 new: permissions: read-all top-level + job-local writes + persist-credentials: false + Scorecard Token-Permissions.score == 10. - SEC-08 new: Semgrep SAST workflow ERROR-blocking + SARIF in code-scanning + required status check; backlog issue tracks ossf/scorecard#5103. - BUILD-07 new: CII Best Practices passing badge in both READMEs + Scorecard CII-Best-Practices.score >= 5. - DOC-11 new: ADR-0009 + SECURITY.md supply-chain section + REQUIREMENTS updates + backlog issues. - Traceability table appended with 5 Phase-6.1 rows; total count 70 -> 75.
8 tasks
yves-vogl
added a commit
to yves-vogl/moneymoney-paypal-pos-extension
that referenced
this pull request
Jun 23, 2026
* docs(06.1): land RESEARCH + PATTERNS + CONTEXT post-Phase-6 addendum
Phase 6.1 (Supply-chain & Scorecard hardening) planning input.
- 06.1-RESEARCH.md (71K): current-state vs CONTEXT D-30..D-36 reconciliation,
pinning strategy, permissions hardening, branch protection deltas, Semgrep
SAST design, CII Best Practices, SBOM/attestation scope recommendation,
egress allowlist refactor, ADR numbering, sequencing recommendation,
open items. Cites live gh API + ossf/scorecard checks.md + Dependabot
changelog + actions/attest-build-provenance + bestpractices.dev.
- 06.1-PATTERNS.md (15K): 14 target files mapped to in-repo analogs.
Calls out CHECKS-array drift in setup-branch-protection.sh and missing
persist-credentials:false across 5 checkout invocations as the two
most load-bearing anti-patterns to guard.
- 06.1-CONTEXT.md addendum: D-30..D-36 status table (D-31/D-32 partially
delivered by Phase 6 CP-2 + ci.yml split; D-30 not delivered).
New decisions D-37..D-41: MkDocs Material docs site (Yves request
2026-06-23), SBOM/attestation deferred to v1.1.x, ADR number 0009
(not 0004 — taken), CII badge in both READMEs, Phase-6 R1 findings
disposition (G-04/05/06/09/10/14 in scope; G-13/15/16 out; S-R2-L-01
in; S-R2-M-01 monitoring-only).
* ci(06.1-02): add explicit .gitleaks.toml inheriting defaults
Closes G-14. The default gitleaks ruleset already covers every secret
shape this repo currently emits; an explicit config file makes the
active ruleset auditable and provides a slot for future project-
specific [[rules]] blocks if a Zettle/PayPal API-key shape ever evades
the default ruleset.
- File is minimal (23 lines), declares [extend] useDefault = true
- No active [[rules]] blocks — only a commented example slot
- Pairs with .gitleaksignore (per-fingerprint allowlist, owned by Phase 6)
- gitleaks-action auto-discovers the config at repo root; no CI YAML change
- Local smoke test: zero findings (gitleaks 8.30.1)
* ci(06.1-01): SHA-pin all 17 action references across 4 workflows
Replace every floating tag (`@v4`, `@v13`, `@v2`, `@v3`, `@v2.4.0`, …)
with a 40-char commit SHA + `# vX.Y.Z` trailing comment per Dependabot
convention. Closes SEC-06 (Pinned-Dependencies) and G-05.
Per-action resolved targets (re-resolved 2026-06-23 via `gh api`):
- actions/checkout v4.2.2 11bd7190
- leafo/gh-actions-lua v13.0.0 6919171c
- leafo/gh-actions-luarocks v6.1.0 35d062de
- gitleaks/gitleaks-action v2.3.9 ff98106e
- actions/upload-artifact v4.6.2 ea165f8d
- actions/download-artifact v4.3.0 d3f86a10
- softprops/action-gh-release v2.6.2 3bb12739
- ossf/scorecard-action v2.4.3 99c09fe9
- github/codeql-action v3.36.2 8272c299
All majors held at currently-pinned line per PLAN guidance
(minimise blast radius — defer v5+/v6+/v7+ bumps to Dependabot review).
Files: 4 workflow files; no src/, tools/, or spec/ changes.
Reproducible-build SHA invariant on dist/paypal-pos.lua preserved
(baseline 18bb7a6a…).
* ci(06.1-01): persist-credentials, top-level read-all, gates hardening
Task 2 of Plan 06.1-01 — surgical hardening across all four workflows:
- ci.yml: add top-level `permissions: read-all` (SEC-07 acceptance bar);
add `persist-credentials: false` to both checkouts (test + secret-scan
jobs) per G-06; extend the D-79 print-gate to also catch `io.write(`
and obvious `local p = print` / `local w = io.write` aliasing (G-04);
add a new permanent SEC-06 grep gate step that walks
`.github/workflows/*.yml` and fails any future PR that introduces a
floating-tag `uses:` reference; replace the brittle
`awk '{print $NF}' | sed 's/%//' | cut -d. -f1` luacov-parser pipeline
with a single awk invocation that emits both the full percentage and
the integer floor (G-09 / PATTERNS §3 row 2).
- release.yml: add `persist-credentials: false` to both checkouts
(verify-signed-tag + build-test-coverage-repro jobs) per G-06 —
`git verify-tag` is local-object-only per RESEARCH §3 A8; replace
the same `awk | sed | cut` anti-pattern at line 139 with the
single-awk pattern (ci.yml and release.yml updated in the same
commit so they cannot drift); tighten the publish job to depend
on `[verify-signed-tag, build-test-coverage-repro]` explicitly
(G-10 defense in depth — a future refactor that drops the chained
needs: cannot silently let an unsigned tag publish).
- commit-lint.yml: add explicit per-job `permissions: { contents: read }`
for SEC-07 textual posture; add `persist-credentials: false` to the
checkout per G-06 (commit-subject lint reads local git objects only).
- scorecard.yml: untouched in this commit (its checkout already carried
`persist-credentials: false` per Phase 6 hardening; Task 1 already
pinned its action references).
Reproducible-build SHA on dist/paypal-pos.lua unchanged
(18bb7a6a…ed8e0c1) — zero src/, tools/, or spec/ modifications.
Closes SEC-07 (Token-Permissions → 10/10 expected), G-04, G-06, G-09,
G-10. SEC-06 closed by Task 1's SHA-pinning + this commit's grep gate
that prevents future regressions.
* ci(06.1-05): group Dependabot github-actions minor+patch updates
Add groups: clause to .github/dependabot.yml github-actions ecosystem
to coalesce minor + patch SHA bumps into one weekly PR. Major-version
bumps stay in separate PRs (breaking-change surface needs attention).
Post Plan 06.1-01, 17 action refs across 4 workflows are SHA-pinned;
without grouping Dependabot would emit one PR per outdated action per
week. The actions-minor-patch group reduces that to typically one
combined PR + zero or one major-version PR.
Also extends the top-of-file comment to document Dependabot's SHA +
trailing version-comment lockstep behaviour (GitHub changelog
2022-10-31; extended Oct 2025 to correct stale comments). Maintainers
must not manually edit the # vX.Y.Z comments — let Dependabot manage
them in lockstep with the SHA.
applies-to: version-updates is explicit so security updates remain
individual PRs (faster turnaround on vulnerabilities).
* ci(06.1-03): add semgrep SAST workflow
- new .github/workflows/sast.yml runs Semgrep on push (main, phase-*) + PR (any)
- ruleset: p/security-audit + p/secrets (D-34); --error makes ERROR-severity blocking (D-33)
- SARIF upload via github/codeql-action/upload-sarif with if: always() so findings surface even on failure
- pip install semgrep==1.167.0 (NOT container, avoids Docker Hub rate-limit per RESEARCH Pitfall 7)
- SHA-pinned uses: actions/checkout@11bd719 (v4.2.2),
actions/setup-python@a309ff8 (v6.2.0),
github/codeql-action@8272c29 (v3.36.2)
- top-level permissions: read-all; job permissions: security-events:write + actions:read + contents:read
- checkout: persist-credentials: false + fetch-depth: 0
- job name 'Semgrep SAST' (load-bearing for Plan 06.1-04 branch-protection CHECKS array)
- --exclude spec avoids JWT-shaped test fixtures (RESEARCH §5)
- local dry-run (semgrep 1.167.0 against src/**) returned 0 findings, 0 suppressions needed
Closes SEC-08 (the security control). Scorecard SAST score reporting deferred
to upstream ossf/scorecard#5103 — ADR-0009 (Plan 06.1-08) documents the gap.
* docs(06.1-03): complete semgrep SAST workflow plan
Add SUMMARY.md documenting the .github/workflows/sast.yml landing:
- ruleset p/security-audit + p/secrets, ERROR-blocking, SARIF upload
- SHA-pinned actions (checkout v4.2.2, setup-python v6.2.0, upload-sarif v3.36.2)
- pip install semgrep==1.167.0 (not container)
- local dry-run on src/** returned 0 findings, 0 suppressions
- Scorecard SAST score gap documented (ossf/scorecard#5103 upstream pending)
- branch-protection CHECKS update deferred to Plan 06.1-04 (deadlock prevention)
* fix(06.1-03): switch semgrep ci → semgrep scan (--error not supported by ci)
First push of sast.yml failed in CI (run 28026173380):
'semgrep ci: unknown option --error'
The 'semgrep ci' subcommand is hard-wired to the Semgrep AppSec Platform
login flow and does not accept --error (per Semgrep CLI 1.167.0 `--help`).
'semgrep scan' is the offline-friendly equivalent that honors --error to
flip the exit code on ERROR-severity findings without requiring a token.
Same rules (p/security-audit + p/secrets), same SARIF output, same exclude
patterns. Adds --metrics=off for full offline determinism.
Local re-verification on src/** with the new invocation: 0 findings,
exit 0, SARIF file (514 KB) produced.
Rule 1 deviation — bug introduced by the plan text (Plan 06.1-03 Task 2
codified 'semgrep ci --error' which is not a valid invocation). Plan
intent (ERROR-severity blocking via SARIF upload) preserved byte-for-byte.
* docs(06.1-06): mkdocs material site config + bilingual landing pages
Closes D-37 (in part — workflow follows in the next commit).
Adds MkDocs Material site config and content pages that nav into existing
Markdown source-of-truth files (README.de.md, README.md, CONTRIBUTING.md,
SECURITY.md, CHANGELOG.md, ADRs 0001-0008) via mkdocs-include-markdown-plugin —
zero content duplication.
Files:
- mkdocs.yml — site config, Material theme, mkdocs-static-i18n (de default,
en fallback per D-70/D-71), include-markdown for nav-referenced root files,
validation tolerance for cross-repo relative links inside included Markdown
- docs/index.md — German landing
- docs/en/index.md — English landing (i18n override)
- docs/readme.md, docs/security.md, docs/contributing.md, docs/changelog.md —
include-markdown wrappers for root Markdown
- docs/en/readme.md — English README inlined (other docs fall back to default
locale automatically)
Forward reference to ADR-0009 (Plan 06.1-08) is commented out in nav so
`mkdocs build --strict` passes; 06.1-08 will uncomment.
Local validation: `mkdocs build --strict` exits 0 against mkdocs 1.6.1,
mkdocs-material 9.5.41, mkdocs-static-i18n 1.2.3, mkdocs-include-markdown-plugin
7.0.0 (the versions pinned in the docs.yml workflow).
* ci(06.1-06): add docs build + GitHub Pages deploy workflow (SHA-pinned)
Closes D-37 (workflow track).
New workflow .github/workflows/docs.yml:
- Triggers: push to main → build + deploy; PR → build-only validate;
workflow_dispatch → manual rebuild
- Top-level `permissions: read-all` (SEC-07); deploy job escalates to
pages: write + id-token: write + contents: read (minimum required by
actions/deploy-pages OIDC verification)
- All actions SHA-pinned (SEC-06): checkout v4.2.2, setup-python v5.3.0,
upload-pages-artifact v3.0.1, deploy-pages v4.0.5
- persist-credentials: false on checkout (G-06)
- concurrency: group=pages, cancel-in-progress=false (GitHub-recommended
Pages pattern)
- Pinned Python toolchain: mkdocs 1.6.1, mkdocs-material 9.5.41,
mkdocs-static-i18n 1.2.3, mkdocs-include-markdown-plugin 7.0.0
(deterministic builds; manual bump until Plan 06.1-05 follow-up extends
Dependabot to the pip ecosystem — T-06.1-06-01/SC mitigation)
- Build step: `mkdocs build --strict`
- Deploy step gated on `github.event_name == 'push' && github.ref == 'refs/heads/main'`
Yves CP-6.1-C (one-time precondition before first deploy succeeds):
Open https://github.com/yves-vogl/moneymoney-paypal-pos-extension/settings/pages
Source: "GitHub Actions" (not "Deploy from a branch"), then Save.
After this enablement, the workflow auto-deploys on push to main and the
site renders at https://yves-vogl.github.io/moneymoney-paypal-pos-extension/.
* docs(06.1-06): add Documentation/Dokumentation badge to bilingual READMEs
Closes D-40 (bilingual badge cluster).
Single-line insertion in each README's badge cluster, between the OpenSSF
Scorecard badge and the GitHub Sponsors badge:
- README.md → "Documentation" (English label)
- README.de.md → "Dokumentation" (German label)
Both badges link to https://yves-vogl.github.io/moneymoney-paypal-pos-extension/
(the Pages site shipped by ci(06.1-06) workflow). No other content change in
either README — surgical edit only.
* docs(06.1-06): complete MkDocs Material site plan
* docs(06.1-03): update SUMMARY with Rule 1 fix + CI-green confirmation
- Document semgrep ci → semgrep scan Rule 1 fix (commit 27d7476)
- Record all three CI run IDs (28026173380 failed, 28026276896 failed,
28026375102 GREEN)
- Add deferred-items.md entries for Node 20 + CodeQL Action v3 deprecations
(both shared with Plan 06.1-01 SHAs; sync bump needed in Plan 06.1-05 or
a dedicated follow-on)
* docs(06.1): land 8 plan files + PLAN-INDEX from planner
Plans 06.1-01 through 06.1-08 (Wave 1-5) + PLAN-INDEX (dependency graph
+ cumulative Scorecard delta). Authored by gsd-planner 2026-06-23 with
inputs from CONTEXT (D-30..D-41 incl. addendum) + RESEARCH (11 sections)
+ PATTERNS (14 file mappings).
Plans 01/02/03/05/06 already executed and on branch; this commit lands
the source-of-truth plan documents so the consolidator (06.1-08) and the
verifier have the canonical task lists available.
* ci(06.1-04): wire SCORECARD_READ_TOKEN into scorecard-action
Add `repo_token: ${{ secrets.SCORECARD_READ_TOKEN }}` as a `with:` input
to the ossf/scorecard-action step so the Branch-Protection Scorecard
check can introspect main's protection state via a fine-grained PAT
(Administration: read). Without it scorecard-action falls back to the
default GITHUB_TOKEN, which cannot read branch-protection, and the
Branch-Protection check returns -1 (unreadable).
Closes SEC-05 expansion (Branch-Protection introspection).
Yves checkpoints (must run by hand — script run NOT included here):
CP-6.1-A (BEFORE merge): Yves creates a fine-grained PAT
- Resource owner: yves-vogl
- Repository access: moneymoney-paypal-pos-extension only
- Repository permissions: Administration -> Read-only (and nothing else)
- Expiration: 1 year (rotation cadence captured in SECURITY.md by 06.1-08)
Then:
gh secret set SCORECARD_READ_TOKEN \
--repo yves-vogl/moneymoney-paypal-pos-extension
Verify:
gh secret list --repo yves-vogl/moneymoney-paypal-pos-extension \
| grep SCORECARD_READ_TOKEN
If the secret is unset when scorecard.yml's next run fires (cron
or push to main), the Branch-Protection check returns -1 for the
next ~24 h of cached score.
CP-6.1-B (AFTER merge): companion commit chore(06.1-04) updates
tools/setup-branch-protection.sh; Yves runs the script post-merge
to push the new 5-check CHECKS array into live protection on main.
SHA pinning (06.1-01) and top-level `permissions: read-all` preserved.
* chore(06.1-04): extend setup-branch-protection.sh CHECKS + S-R2-L-01 assertions
Three surgical edits to tools/setup-branch-protection.sh:
1. CHECKS array grows from 3 to 5 entries. Adds:
- "Scorecard analysis" (matches scorecard.yml job name byte-exact)
- "Semgrep SAST" (matches sast.yml job name byte-exact)
Both strings verified against the workflow `name:` declarations
in this same branch — string-drift here would silently deadlock
every PR waiting for a non-existent check-run context.
2. Manual-UI fallback block (used when the running PAT lacks
`Administration: write`) gains the same two bullet entries so a
maintainer falling back to the GitHub UI configures all 5 required
checks in lockstep.
3. Post-condition GET adds S-R2-L-01 hardening: two new jq assertions
on the read-back protection JSON for
`.allow_force_pushes.enabled == false`
`.allow_deletions.enabled == false`
The PUT payload already declares both as false; the assertions
catch silent partial-apply by the GitHub API.
Final OK line updated to mention both new invariants.
`bash -n tools/setup-branch-protection.sh` passes cleanly.
The script is NOT run in this commit. Yves runs it post-merge as the
existing CP-2 pattern. Companion commit ci(06.1-04) wires the
SCORECARD_READ_TOKEN secret into scorecard.yml.
Closes S-R2-L-01 (branch-protection post-condition assertions for
allow_force_pushes + allow_deletions).
* docs(06.1-04): land SUMMARY + STATE bump for scorecard token + CHECKS extension
Records the two-commit execution of Plan 06.1-04:
184b2f6 ci(06.1-04): wire SCORECARD_READ_TOKEN into scorecard-action
93684aa chore(06.1-04): extend setup-branch-protection.sh CHECKS + S-R2-L-01 assertions
SUMMARY captures:
- byte-exact job-name audit trail (CHECKS entries vs workflow `name:` declarations)
- both Yves CPs (CP-6.1-A pre-merge secret provisioning, CP-6.1-B post-merge script run)
- threat-model coverage notes
- self-check confirmation (file presence + commit GPG signatures)
STATE last_updated + Session Continuity bumped to reflect Phase 6.1 wave-3 progress.
Closes SEC-05 expansion + S-R2-L-01 (executor side; live protection update
gated on CP-6.1-B by Yves post-merge).
* docs(06.1-08): adr-0009 openssf scorecard stance
Documents the bewusst akzeptierten Gaps (Fuzzing 0/10, Code-Review 0/10,
Packaging -1, Contributors structural, Maintained heals-itself) with
compensating mitigations and Alternatives Considered (Option B 1-reviewer,
Option C bot-reviewer, Snyk Code, SBOM+cosign+SLSA deferred to v1.1.x,
G-09 awk shell-interpolation low-severity, Lua/CI Semgrep rulesets).
Revises the Phase-6.1 aggregate target: ≥ 7.5 short-term, ≥ 8.5 once
ossf/scorecard#5103 merges (SAST 0→10) AND repo age crosses 90 days
(Maintained 0→8+, ~2026-09-15).
Closes DOC-11 (in concert with this plan's SECURITY.md + REQUIREMENTS.md
+ ROADMAP.md edits).
* docs(06.1-08): security.md supply-chain controls section
Adds bilingual 'Lieferketten-Kontrollen / Supply-chain controls' sections
listing all 10 active controls (SHA-pinned actions, least-privilege tokens,
Semgrep SAST, branch protection, Scorecard introspection, gitleaks,
signed releases, reproducible build, redact-before-log, egress allowlist)
plus the SCORECARD_READ_TOKEN rotation runbook (≤1y expiry).
Cross-references ADR-0009 for the trade-off rationale. Mirrors the
existing DE-primary / EN-follows structure; no content above the
insertion points changed.
* chore(06.1-08): requirements bumps for SEC-05..08 BUILD-07 DOC-11
- SEC-05 modified in-place: expanded with SCORECARD_READ_TOKEN provisioning,
branch-protection invariants (linear history, no force-push/delete, no admin
bypass), 5 required status checks, Scorecard Branch-Protection.score >= 3
(Tier 1; Option A locked per ADR-0009).
- SEC-06 new: SHA-pinned uses: refs in workflows + CI grep gate + Dependabot
lockstep + Scorecard Pinned-Dependencies.score == 10.
- SEC-07 new: permissions: read-all top-level + job-local writes +
persist-credentials: false + Scorecard Token-Permissions.score == 10.
- SEC-08 new: Semgrep SAST workflow ERROR-blocking + SARIF in code-scanning +
required status check; backlog issue tracks ossf/scorecard#5103.
- BUILD-07 new: CII Best Practices passing badge in both READMEs + Scorecard
CII-Best-Practices.score >= 5.
- DOC-11 new: ADR-0009 + SECURITY.md supply-chain section + REQUIREMENTS
updates + backlog issues.
- Traceability table appended with 5 Phase-6.1 rows; total count 70 -> 75.
* docs(06.1-08): roadmap + state reconciliation + mkdocs adr-0009 nav
- ROADMAP.md: Phase 6.1 success criteria amended (aggregate >=7.5 short-term;
Branch-Protection >=3 per Option A; SAST deferred-acceptance per ADR-0009;
ADR file number 0009 not 0004; both READMEs for CII badge per D-40; new
criterion #9 for MkDocs site per D-37). Phase 6.1 marked [x]. Progress
Table appended with 'Phase 6.1 | 8/8 | Complete | 2026-06-23'.
- STATE.md: re-authoritatively rewritten with post-Phase-6.1 reality.
status: v1.0.0-shipped-pending-tag-and-6.1-shipped; completed_phases: 7;
Phase 6.1 ship summary documented; CP-6.1-A..D + CP-Post-08 surfaced as
Yves tasks; CP-4/5 still pending; metrics row for Phase 6.1 added.
- mkdocs.yml: ADR-0009 nav entry un-commented (Plan 06.1-06 forward-reference
resolved); nav_translations entry for EN locale added.
* docs(06.1-08): SUMMARY for plan 06.1-08 (consolidating docs batch)
Records: 4 commits (852cc88 ADR / 7f79a5f SECURITY / 3a42da8 REQUIREMENTS
/ 78dd7b4 ROADMAP+STATE+mkdocs), all gates green, META-03 walker 3/0/0/0,
reproducible-build SHA unchanged (no src/ edits), Yves post-merge tasks
(CP-6.1-A/B/C/Post-08) surfaced.
* fix(06.1-04): repair ci.yml YAML block-scalar in D-79 alias gate
The Plan-06.1-01 extension of the D-79 raw-print() gate concatenated
BAD and BAD_ALIAS with a literal mid-string newline at column 0:
if [ -n "${BAD}" ]; then BAD="${BAD}
${BAD_ALIAS}"; else BAD="${BAD_ALIAS}"; fi
The unindented "${BAD_ALIAS}" line terminated the YAML literal block
scalar prematurely (block scalars are bounded by indent restoration),
and GitHub Actions rejected the workflow with a YAML parse error on
every push since 89f4ee4. Refactor to printf concatenation that stays
inside the indented block:
BAD="${BAD_CALLS}"
if [ -n "${BAD_ALIAS}" ]; then
BAD="$(printf '%s\n%s' "${BAD}" "${BAD_ALIAS}")"
fi
Semantically identical (same final BAD content); structurally valid YAML.
Verified via python -c "yaml.safe_load(...)" → OK.
* fix(06.1-r): bump mkdocs-include-markdown-plugin past CVE-2025-59940 (S-01)
* fix(06.1-r): extend branch-protection post-condition assertions (S-03 + P6.1-R-04)
* fix(06.1-r): add EN locale include wrappers for --strict build (P6.1-R-01)
* docs(06.1-r): list ADR-0009 in bilingual landing pages (P6.1-R-02)
* docs(06.1-r): ROADMAP coverage counter + Scorecard target reconciliation (P6.1-R-03)
|
This pull request has been marked stale because it has been open for 10 days with no activity |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What kind of change does this PR introduce?
Feature — expands SAST tool detection in the
SASTcheck.What is the current behavior?
The
SASTcheck detects CodeQL, Sonar, Snyk, Pysa, Qodana, and Hadolint. Threewidely deployed open-source SAST tools are not recognized:
semgrep/semgrep, legacyreturntocorp/semgrep-action)PyCQA/bandit-action) — the de facto Python SASTsecurego/gosec,securecodewarrior/github-action-gosec) — the de facto Go SASTRepositories that run these tools in CI are currently scored as if they have no
SAST configured. This is a false negative: a project with real static analysis
coverage receives a lower SAST score than its security posture warrants.
What is the new behavior (if this is a feature change)?
The
SASTcheck now also detects Semgrep, Bandit, and gosec when invoked as aGitHub Action. Detection follows the exact existing
getSastUsesWorkflowspattern used for CodeQL/Snyk/Qodana/Hadolint — each tool gets an anchored
uses:regex and a matchingSASTWorkflowTypeconstant. ThesastToolConfiguredprobe consumes the new workflow types automatically (itmaps
SASTWorkflow.Typestraight to a finding value, so no probe change isrequired).
Changes:
checker/raw_result.go: addSemgrepWorkflow,BanditWorkflow,GosecWorkflowconstants afterHadolintWorkflow.checks/raw/sast.go: add threegetSastUsesWorkflowscalls with anchored regexes.checks/raw/sast_test.go: addHas Semgrep/Has Bandit/Has gosectable cases.checks/raw/testdata/.github/workflows/: add three workflow fixtures using the real action references.docs/checks/sast/README.md: list the three newly supported tools.Tests for the changes have been added (for bug fixes/features)
Security rationale
SAST is a primary control against the introduction of injection, deserialization,
path-traversal, and hardcoded-secret defects (CWE-79, CWE-89, CWE-22, CWE-502,
CWE-798). Scorecard's SAST signal feeds downstream supply-chain risk decisions; a
false negative here understates the real assurance level of a dependency and can
nudge consumers toward unwarranted manual review or, worse, away from a project
that is in fact well-instrumented.
Semgrep, Bandit, and gosec are among the most commonly adopted open-source SAST
tools across the JavaScript/Python/Go ecosystems, so closing this gap materially
improves the accuracy of the SAST score for a large slice of the OSS population.
The detection regexes are fully anchored (
^...$) on the action repositoryreference, so they match the canonical tool actions and their documented legacy
aliases while rejecting look-alike forks and typosquats
(
semgrep/semgrep-app-action,securego/gosec-installer,PyCQA/bandit-action-forkdo not match). This keeps false-positive risk minimal, consistent with the
existing CodeQL/Qodana matchers.
Which issue(s) this PR fixes
NONE
Special notes for your reviewer
semgrep/semgrepaction andthe legacy
returntocorp/semgrep-action, since both are still in active useacross repositories.
securego/gosecaction and the oldersecurecodewarrior/github-action-gosecwrapper.uses:) detection to mirror theexisting pattern exactly and keep false-positive risk low. Config-file
detection (e.g.
.semgrep.yml,.bandit) is a reasonable follow-up but isnoisier (these files are frequently present without CI enforcement), so I left
it out of this PR; happy to add it in a follow-up if maintainers want it.
Does this PR introduce a user-facing change?
Yes — repositories that run Semgrep, Bandit, or gosec via GitHub Actions will now
have those tools recognized by the SAST check.