secret-scan: gitleaks -> betterleaks + zentrale Rausch-Filter
quality / python-lint (push) Skipped
quality / node-lint (push) Skipped
quality / php-lint (push) Skipped
quality / secret-scan (push) Successful in 7s
quality / actionlint (push) Successful in 6s
quality / vuln-scan (push) Successful in 19s
quality / sast (push) Successful in 31s
selftest / quality (push) Successful in 32s

gitleaks ist feature-frozen (letztes Release 03/2026, nur noch
Security-Patches); die Maintainer inkl. Original-Autor entwickeln
betterleaks weiter (MIT, aktive Releases, Secret-Validierung).

- besserleaks-Standardregeln via [extend] useDefault
- [allowlist]: Beispiele (*.example/*.sample/*.template), i18n-JSON,
  node_modules/vendor/dist/Lockfiles, Fixtures -> kein Alarm
- .env/.env.prod, docker-compose, Code und echte Configs bleiben hart
- pro Repo: .betterleaks.toml hat Vorrang, .betterleaksignore fuer
  akzeptierte Altlasten (Fingerprint je Zeile)
- USAGE.md: Abschnitt zum Wechsel + Filterrichtlinie

Verifiziert an den 5 auffaelligen Repos: gitleaks 34 Treffer -> betterleaks
58, nach Filterrichtlinie 35 (Rauschen entfernt, echte Funde bleiben).
This commit is contained in:
root
2026-09-11 09:53:53 +00:00
parent 26023818db
commit 235f7b106a
2 changed files with 64 additions and 9 deletions
+40 -7
View File
@@ -1,7 +1,8 @@
name: quality
# Reusable Quality-Gate. Scans laufen per DEFAULT (opt-out via skip_*),
# Sprach-Linter opt-in (python/node/php). Report-only per Default;
# blocking=true macht SAST/Vuln/Lint hart. Secrets sind IMMER hart.
# blocking=true macht SAST/Vuln/Lint hart. Secrets sind IMMER hart
# (betterleaks - Nachfolger von gitleaks; gitleaks ist feature-frozen).
# Runner=catthehacker (Debian, PEP668) -> pip mit --break-system-packages.
# KEINE Docker-Hub-Pulls -> Tools via GitHub-Release/pip.
on:
@@ -22,14 +23,46 @@ jobs:
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- name: gitleaks (Secrets = immer blockierend)
- name: betterleaks (Secrets = immer blockierend)
run: |
set -eo pipefail
GLV=$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/gitleaks/gitleaks/releases/latest | sed 's#.*/tag/v##')
[ -n "$GLV" ] || GLV=8.21.2
echo "::notice::gitleaks v$GLV"
curl -fsSL "https://github.com/gitleaks/gitleaks/releases/download/v${GLV}/gitleaks_${GLV}_linux_x64.tar.gz" | tar -xz -C /tmp gitleaks
/tmp/gitleaks detect --source . --redact --no-banner --exit-code 1
BLV=$(curl -fsSL -o /dev/null -w '%{url_effective}' https://github.com/betterleaks/betterleaks/releases/latest | sed 's#.*/tag/v##')
[ -n "$BLV" ] || BLV=1.8.1
echo "::notice::betterleaks v$BLV"
curl -fsSL "https://github.com/betterleaks/betterleaks/releases/download/v${BLV}/betterleaks_${BLV}_linux_x64.tar.gz" | tar -xz -C /tmp betterleaks
# Zentrale Richtlinie: betterleaks-Standardregeln plus Ausschluss von
# strukturellem Rauschen (Beispiel-Dateien, Uebersetzungen, Abhaengigkeiten,
# Build-Artefakte). Echte Funde in .env(.prod)/docker-compose/Code/Config
# bleiben hart und lassen den Job fehlschlagen.
cat > /tmp/betterleaks.toml <<'BE_CFG'
[extend]
useDefault = true
[allowlist]
description = "digiflo: strukturelles Rauschen (Beispiele, i18n, Abhaengigkeiten, Build)"
paths = [
'''(?:^|/)node_modules(?:/.*)?$''',
'''(?:^|/)vendor(?:/.*)?$''',
'''(?:^|/)(?:dist|build|coverage|\.next|\.nuxt)(?:/.*)?$''',
'''(?:^|/)(?:package-lock\.json|pnpm-lock\.yaml|yarn\.lock)$''',
'''(?i)(?:^|/)[^/]*\.(?:example|sample|template|dist|bak|orig)$''',
'''(?i)\.env\.(?:example|sample|template)$''',
'''(?i)(?:^|/)(?:i18n|locales?|lang)(?:/.*)?\.json$''',
'''(?i)(?:^|/)templates?/.*\.(?:json|ya?ml|php|ts|js|py|sh)$''',
'''(?i)(?:^|/)(?:__snapshots__|testdata|fixtures?)(?:/.*)?$''',
]
stopwords = [
"example", "sample", "placeholder", "changeme", "change_me",
"your_password", "your-password", "dummy", "redacted", "not_a_real",
]
BE_CFG
# Repo-eigene Richtlinie hat Vorrang. Akzeptierte Altlasten werden per
# .betterleaksignore im Repo-Root hinterlegt (Fingerprint je Zeile).
CFG=/tmp/betterleaks.toml
if [ -f .betterleaks.toml ]; then CFG=.betterleaks.toml; fi
/tmp/betterleaks git . --config "$CFG" --redact --no-banner --exit-code 1
sast:
if: ${{ !inputs.skip_sast }}
+24 -2
View File
@@ -1,8 +1,30 @@
# ci-templates — org-weites Quality-Gate
Reusable Workflow fuer alle Orgs. Scans (gitleaks/semgrep/trivy/actionlint) laufen per
Reusable Workflow fuer alle Orgs. Scans (betterleaks/semgrep/trivy/actionlint) laufen per
**Default**; Sprach-Linter (python/node/php) sind **opt-in**. **Report-only** per Default,
`blocking: true` macht SAST/Vuln/Lint zum harten Gate. **Secrets (gitleaks) sind IMMER hart.**
`blocking: true` macht SAST/Vuln/Lint zum harten Gate. **Secrets (betterleaks) sind IMMER hart.**
## Secret-Scan: betterleaks statt gitleaks (seit 2026-09-11)
gitleaks ist **feature-frozen** (letztes Release 03/2026, nur noch Security-Patches);
die Maintainer inkl. Original-Autor entwickeln **betterleaks** weiter (v1.8.1, MIT,
aktive Releases). betterleaks findet in denselben Repos deutlich mehr als gitleaks
(Bsp.: 34 -> 58 Treffer), kann Secrets per `validate` auf "noch aktiv?" pruefen und
filtert Rauschen per Expr-Regeln.
Zentrale Richtlinie liegt inline im Job `secret-scan` (`[extend] useDefault = true`
+ `[allowlist]`): Beispiel-Dateien (`.env.example`, `*.sample`, `*.template`),
Uebersetzungen (`i18n/*.json`), Abhaengigkeiten/Build (`node_modules`, `vendor`,
`dist`, Lockfiles) und Fixtures werden nicht gemeldet. **Nicht** ausgeschlossen:
`.env`/`.env.prod`, `docker-compose*`, Code und echte Config-Dateien - dort laesst
ein Fund den Gate fehlschlagen.
Pro Repo:
- `.betterleaks.toml` im Repo-Root **ersetzt** die zentrale Richtlinie (Vorrang).
- `.betterleaksignore` im Repo-Root nimmt einzeln akzeptierte Altlasten auf;
Format = `Fingerprint` aus dem JSON-Report: `<commit>:<pfad>:<regel>:<zeile>`.
Details zum Fund liefert der Job-Log; Fingerprints lokal per
`betterleaks git . --report-format json --report-path r.json`.
- Inline-Ausnahme direkt im Code: Kommentar `betterleaks:allow` in der Zeile.
## WICHTIG — Sichtbarkeit (Gitea-Limitation, verifiziert 2026-08-25)
Private reusable Workflows koennen von anderen Repos NICHT gelesen werden