feat(ci): geheimen- en SAST-scan draaien nu in CI (#778) #785

Closed
brenno wants to merge 1 commit from feat/ci-scans-778 into main
Owner

Closes #778.

make check staat sinds #741 op de runner. check-secrets (gitleaks +
trufflehog) en sast (semgrep) zaten alleen in check-full, en dat draait
nergens automatisch — of er ooit gescand was, hing af van wie het lokaal
toevallig deed. Voor een geheim telt alleen of het vóór de merge gevonden
wordt; daarna staat het in de historie.

Geen bekend lek. Ik heb beide handmatig op main gedraaid: schoon, en semgrep
0 bevindingen over 690 bestanden. Dit dicht de controle, niet een gat.

Waarom nu

De rechtvaardiging voor het gat staat opgeschreven in check_conventions.dart
bij nosemgrepBaseline"het vraagt een externe binary" — en ging over de
machine van een bijdrager. In een container bepaal je zelf wat erin zit. Het is
dus geen nieuwe afweging maar een vervallen beperking.

Twee dingen die het gewicht dragen

fetch-depth: 0. Zonder dit is de job theater: actions/checkout kloont één
commit diep, en gitleaks git / trufflehog git scannen de histórie. Op een
ondiepe kloon kijken ze naar bijna niets en melden groen — terwijl een geheim
dat drie commits terug is toegevoegd en daarna "verwijderd" precies het geval is
dat deze pas moet vinden.

Gepinde versies, geverifieerde download. Zelfde discipline als de
Flutter-stap. De test -n "$SHA" daarin is geen plichtpleging: ik heb gemeten
dat grep … | sha256sum -c - stil slaagt met exit 0 zodra de grep niets
vindt. Eén hernoemd release-asset en de verificatie is weg zonder één rood
vinkje. Dat was een fout in mijn eigen eerste versie.

Tegenproef

De poort is rood gezien met een geplant sleutelpaar in een commit:

Geplante waarde gitleaks trufflehog
AKIAIOSFODNN7EXAMPLE (AWS' eigen documentatievoorbeeld) zwijgt zwijgt
willekeurig gegenereerd paar exit 1 exit 183

Dat eerste is terecht — die waarde staat in de standaardregels op een
uitzonderingslijst. Het is ook de reden dat zo'n tegenproef mét een dummy niets
bewijst; met de dummy zou ik hebben geconcludeerd dat de poort tandeloos is.
De commit is daarna volledig uit de tak verwijderd en gitleaks git bevestigt
dat er geen spoor van over is.

Wat er bewust buiten blijft

DAST (ZAP) — de webbundel is CanvasKit; een spider komt niet door een canvas.
Het geserveerde oppervlak dekt make check-web al.
De adviserende doelen (deps-outdated, catalogs-outdated) — die verouderen
buiten je schuld en horen niet rood te kunnen worden op andermans PR.

Semgrep is op versie gepind maar niet hash-gepind. Het komt van PyPI; de
transitieve afhankelijkheden hash-pinnen vraagt een eigen requirements-bestand
met honderden hashes, en dat onderhouden is een grotere belofte dan hier
waargemaakt wordt. Staat als zodanig in het commentaar in plaats van stilzwijgend.

Poorten

make check, make check-secrets, make sast en make shellcheck alle vier
exit 0 op deze tak. Geen Dart-wijziging, geen l10n, geen SBOM-gevolg.
docs/CHECKS.md bij.

Deze PR toetst zichzelf: de nieuwe job draait op deze pull request. Als
scans hier groen is, is dat het bewijs dat de workflow werkt op de echte
runner — dat kan ik lokaal niet nabootsen.

Closes #778. `make check` staat sinds #741 op de runner. `check-secrets` (gitleaks + trufflehog) en `sast` (semgrep) zaten alleen in `check-full`, en dat draait nergens automatisch — of er ooit gescand was, hing af van wie het lokaal toevallig deed. Voor een geheim telt alleen of het *vóór* de merge gevonden wordt; daarna staat het in de historie. **Geen bekend lek.** Ik heb beide handmatig op main gedraaid: schoon, en semgrep 0 bevindingen over 690 bestanden. Dit dicht de controle, niet een gat. ## Waarom nu De rechtvaardiging voor het gat staat opgeschreven in `check_conventions.dart` bij `nosemgrepBaseline` — *"het vraagt een externe binary"* — en ging over de machine van een bijdrager. In een container bepaal je zelf wat erin zit. Het is dus geen nieuwe afweging maar een vervallen beperking. ## Twee dingen die het gewicht dragen **`fetch-depth: 0`.** Zonder dit is de job theater: `actions/checkout` kloont één commit diep, en `gitleaks git` / `trufflehog git` scannen de histórie. Op een ondiepe kloon kijken ze naar bijna niets en melden groen — terwijl een geheim dat drie commits terug is toegevoegd en daarna "verwijderd" precies het geval is dat deze pas moet vinden. **Gepinde versies, geverifieerde download.** Zelfde discipline als de Flutter-stap. De `test -n "$SHA"` daarin is geen plichtpleging: ik heb gemeten dat `grep … | sha256sum -c -` **stil slaagt met exit 0** zodra de grep niets vindt. Eén hernoemd release-asset en de verificatie is weg zonder één rood vinkje. Dat was een fout in mijn eigen eerste versie. ## Tegenproef De poort is rood gezien met een geplant sleutelpaar in een commit: | Geplante waarde | gitleaks | trufflehog | |---|---|---| | `AKIAIOSFODNN7EXAMPLE` (AWS' eigen documentatievoorbeeld) | zwijgt | zwijgt | | willekeurig gegenereerd paar | exit 1 | exit 183 | Dat eerste is terecht — die waarde staat in de standaardregels op een uitzonderingslijst. Het is ook de reden dat zo'n tegenproef mét een dummy niets bewijst; met de dummy zou ik hebben geconcludeerd dat de poort tandeloos is. De commit is daarna volledig uit de tak verwijderd en `gitleaks git` bevestigt dat er geen spoor van over is. ## Wat er bewust buiten blijft **DAST (ZAP)** — de webbundel is CanvasKit; een spider komt niet door een canvas. Het geserveerde oppervlak dekt `make check-web` al. **De adviserende doelen** (`deps-outdated`, `catalogs-outdated`) — die verouderen buiten je schuld en horen niet rood te kunnen worden op andermans PR. **Semgrep is op versie gepind maar niet hash-gepind.** Het komt van PyPI; de transitieve afhankelijkheden hash-pinnen vraagt een eigen requirements-bestand met honderden hashes, en dat onderhouden is een grotere belofte dan hier waargemaakt wordt. Staat als zodanig in het commentaar in plaats van stilzwijgend. ## Poorten `make check`, `make check-secrets`, `make sast` en `make shellcheck` alle vier exit 0 op deze tak. Geen Dart-wijziging, geen l10n, geen SBOM-gevolg. `docs/CHECKS.md` bij. **Deze PR toetst zichzelf**: de nieuwe job draait op deze pull request. Als `scans` hier groen is, is dat het bewijs dat de workflow werkt op de echte runner — dat kan ik lokaal niet nabootsen.
feat(ci): geheimen- en SAST-scan draaien nu in CI (#778)
Some checks failed
ci / scans (pull_request) Successful in 51m59s
ci / gate (pull_request) Failing after 1h32m14s
00c1c6eb2b
make check stond sinds #741 op de runner; check-secrets en sast zaten
alleen in check-full, en dat gaat nergens automatisch. Voor een geheim
telt alleen of het vóór de merge gevonden wordt.

De rechtvaardiging voor het gat stond bij nosemgrepBaseline ("het vraagt
een externe binary") en ging over de machine van een bijdrager; in een
container bepaal je zelf wat erin zit. Die beperking verviel toen de
runner er kwam.

Een eigen job, zodat de faalreden leesbaar blijft, en met de Makefile-
doelen als commando in plaats van overgetypte regels — anders lopen
lokaal en CI uit elkaar.

Twee dingen dragen het gewicht:

  * fetch-depth: 0. actions/checkout kloont één commit diep, en beide
    historie-scans melden op een ondiepe kloon groen over vrijwel niets.
  * gepinde versies met een tegen het manifest geverifieerde download.
    De `test -n` daarin is geen plichtpleging: `grep | sha256sum -c -`
    slaagt stil bij een lege treffer. Hier gemeten vóór het erin ging.

Tegenproef gedraaid: met AWS' documentatievoorbeeld zwijgen beide
scanners terecht, met een willekeurig sleutelpaar slaan ze aan.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
brenno closed this pull request 2026-07-24 15:35:49 +00:00
Some checks failed
ci / scans (pull_request) Successful in 51m59s
ci / gate (pull_request) Failing after 1h32m14s

Pull request closed

Sign in to join this conversation.
No description provided.