From 74ae929ab4136d99c0e7d75a30048b025c7b81e2 Mon Sep 17 00:00:00 2001 From: Jannis Braun <151788261+TheZwiss@users.noreply.github.com> Date: Sun, 12 Jul 2026 23:25:26 +0200 Subject: [PATCH] ci(security): add report-only security scan workflow (gitleaks, OSV, Trivy) --- .github/workflows/security.yml | 123 +++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 .github/workflows/security.yml diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 00000000..1596d3a9 --- /dev/null +++ b/.github/workflows/security.yml @@ -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