ci(security): add report-only security scan workflow (gitleaks, OSV, Trivy)

This commit is contained in:
Jannis Braun
2026-07-12 23:51:00 +02:00
parent 807afba45a
commit 74ae929ab4
+123
View File
@@ -0,0 +1,123 @@
name: Security
# Report-only in this plan: every scanner is non-blocking and uploads SARIF to
# the Security tab. Enforcement (fail on fixable HIGH/CRITICAL, block on secrets)
# is flipped on in Plan E after the remediation pass.
on:
pull_request:
push:
branches: [main]
schedule:
- cron: '32 5 * * 1' # weekly Monday 05:32 UTC
permissions:
contents: read
concurrency:
group: security-${{ github.ref }}
cancel-in-progress: true
jobs:
gitleaks:
name: Secret scan (gitleaks)
runs-on: ubuntu-latest
steps:
- name: Harden the runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Checkout (full history)
uses: actions/checkout@v5
with:
fetch-depth: 0 # gitleaks scans the whole git history, not just the diff
- name: Run gitleaks
uses: gitleaks/gitleaks-action@v2
continue-on-error: true # report-only; enforcement flipped on in Plan E
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
osv-scanner:
name: Dependency scan (OSV-Scanner)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write # upload SARIF to code scanning
steps:
- name: Harden the runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@v5
- name: Run OSV-Scanner
uses: google/osv-scanner-action@v2
continue-on-error: true # report-only; enforcement flipped on in Plan E
with:
scan-args: |-
--lockfile=./pnpm-lock.yaml
--format=sarif
--output=osv-results.sarif
- name: Upload OSV SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: osv-results.sarif
category: osv-scanner
trivy-config:
name: IaC/config scan (Trivy)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Harden the runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@v5
- name: Trivy config scan (Dockerfile + docker-compose)
uses: aquasecurity/trivy-action@0.28.0
continue-on-error: true # report-only; enforcement flipped on in Plan E
with:
scan-type: config
scan-ref: .
format: sarif
output: trivy-config.sarif
- name: Upload Trivy config SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-config.sarif
category: trivy-config
trivy-license:
name: License compliance scan (Trivy)
runs-on: ubuntu-latest
permissions:
contents: read
security-events: write
steps:
- name: Harden the runner
uses: step-security/harden-runner@v2
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@v5
- name: Trivy license scan
uses: aquasecurity/trivy-action@0.28.0
continue-on-error: true # report-only; enforcement flipped on in Plan E
with:
scan-type: fs
scan-ref: .
scanners: license
format: sarif
output: trivy-license.sarif
- name: Upload Trivy license SARIF
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-license.sarif
category: trivy-license