chore(deps): bump actions/upload-artifact from 4 to 7 #264
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
| name: Security | |
| # Esegue scansioni di sicurezza supply-chain: | |
| # - trivy sulle 3 immagini buildate localmente (HIGH + CRITICAL, fail) | |
| # - gitleaks sulla git history (fail se trova segreti non-allowed) | |
| # Triggera su PR, push su main e una volta a settimana (per pescare CVE nuove | |
| # pubblicate dopo l'ultimo merge). | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| schedule: | |
| # Lunedi mattina UTC. | |
| - cron: '0 6 * * 1' | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| jobs: | |
| trivy-images: | |
| name: Trivy image scan (${{ matrix.image.name }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| image: | |
| - name: backend | |
| context: . | |
| dockerfile: ./backend/Dockerfile | |
| - name: frontend | |
| context: . | |
| dockerfile: ./frontend/Dockerfile | |
| - name: web | |
| context: ./web | |
| dockerfile: ./web/Dockerfile | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Set up Buildx | |
| uses: docker/setup-buildx-action@v4 | |
| - name: Build image (load local) | |
| uses: docker/build-push-action@v7 | |
| with: | |
| context: ${{ matrix.image.context }} | |
| file: ${{ matrix.image.dockerfile }} | |
| load: true | |
| push: false | |
| tags: accanto-${{ matrix.image.name }}:scan | |
| cache-from: type=gha,scope=sec-${{ matrix.image.name }} | |
| cache-to: type=gha,scope=sec-${{ matrix.image.name }},mode=max | |
| - name: Trivy vulnerability scan | |
| uses: aquasecurity/trivy-action@v0.36.0 | |
| with: | |
| image-ref: accanto-${{ matrix.image.name }}:scan | |
| severity: 'HIGH,CRITICAL' | |
| ignore-unfixed: true | |
| exit-code: '1' | |
| format: 'table' | |
| vuln-type: 'os,library' | |
| gitleaks: | |
| name: Gitleaks (secrets in git history) | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Gitleaks | |
| uses: gitleaks/gitleaks-action@v3 | |
| env: | |
| GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
| # Cerca anche nei branch e nei tag. Falsi positivi noti vanno | |
| # esclusi via .gitleaks.toml (vedi docs/security-audit.md). | |
| GITLEAKS_ENABLE_COMMENTS: false | |
| dotnet-deps: | |
| name: .NET vulnerable & deprecated packages | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET 10 | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Restore | |
| working-directory: backend | |
| run: dotnet restore | |
| # `dotnet list package --vulnerable` ritorna sempre 0 -- bisogna | |
| # parsare l'output. Fallisce il job solo se appare almeno una riga | |
| # 'High' o 'Critical'. 'Moderate' viene segnalato ma non blocca | |
| # (gestito manualmente prima della release). | |
| - name: Scan vulnerable packages | |
| working-directory: backend | |
| run: | | |
| set -euo pipefail | |
| OUT=$(dotnet list package --vulnerable --include-transitive 2>&1) | |
| echo "$OUT" | |
| if echo "$OUT" | grep -E '\b(High|Critical)\b' >/dev/null; then | |
| echo "::error::Vulnerabilita' High/Critical in dipendenze .NET (vedi output)." | |
| exit 1 | |
| fi | |
| - name: Scan deprecated packages (warn-only) | |
| working-directory: backend | |
| continue-on-error: true | |
| run: dotnet list package --deprecated --include-transitive | |
| npm-audit: | |
| name: npm audit (${{ matrix.project }}) | |
| runs-on: ubuntu-latest | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| project: [frontend, web] | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| cache: 'npm' | |
| cache-dependency-path: ${{ matrix.project }}/package-lock.json | |
| - name: Install (no scripts) | |
| working-directory: ${{ matrix.project }} | |
| run: npm ci --ignore-scripts | |
| # Script custom: fallisce su High/Critical NON in allowlist. | |
| # Allowlist per-progetto in <project>/.npm-audit-allow (tracciata in git, | |
| # con motivo + scadenza per ogni eccezione). | |
| - name: Audit (allowlist-aware) | |
| working-directory: ${{ matrix.project }} | |
| run: bash ../scripts/ci/npm-audit-check.sh ./.npm-audit-allow | |
| sbom: | |
| name: SBOM (CycloneDX) | |
| runs-on: ubuntu-latest | |
| # Genera l'inventario firmato delle dipendenze per backend (.NET) e | |
| # per i due progetti JS (frontend SPA + sito vetrina). Formato: | |
| # CycloneDX 1.5 JSON, standard de-facto consumabile da Dependency-Track, | |
| # Grype, OSV-Scanner, Snyk e dai tool di compliance (NTIA SBOM, EO 14028). | |
| # | |
| # Differenza vs dotnet-deps/npm-audit: questi job FALLISCONO la build se | |
| # trovano vuln High/Critical. La SBOM invece e' un ARTIFACT della build, | |
| # utilizzabile per: | |
| # - re-scan offline quando una nuova CVE viene pubblicata (senza | |
| # dover ri-buildare l'app) | |
| # - audit di compliance (clienti enterprise / sanitario chiedono SBOM) | |
| # - tracking delle dipendenze nel tempo (delta tra release) | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - name: Setup .NET 10 | |
| uses: actions/setup-dotnet@v5 | |
| with: | |
| dotnet-version: '10.0.x' | |
| - name: Setup Node | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: '20' | |
| - name: Install CycloneDX .NET tool | |
| run: dotnet tool install --global CycloneDX | |
| - name: Generate backend SBOM | |
| working-directory: backend | |
| run: | | |
| set -euo pipefail | |
| mkdir -p ../sbom | |
| # CycloneDX .NET v6: -j/-o short flags rimossi/cambiati (-t ora | |
| # significa --exclude-test-projects). Usiamo long form: | |
| # --output-format Json (al posto del deprecato --json) e | |
| # --output <dir> (al posto del deprecato --out). | |
| # Eseguiamo sul solo progetto runtime (Accanto.Api): include | |
| # tutte le dipendenze dei progetti referenziati (Application, | |
| # Domain, Infrastructure) ma esclude le dev/test deps di | |
| # Accanto.Tests, che NON finiscono nei container di produzione. | |
| dotnet CycloneDX src/Accanto.Api/Accanto.Api.csproj \ | |
| --output-format Json \ | |
| --output ../sbom \ | |
| --filename backend.cdx.json | |
| - name: Install CycloneDX npm tool | |
| run: npm install -g @cyclonedx/cyclonedx-npm | |
| - name: Generate frontend SBOM | |
| working-directory: frontend | |
| run: | | |
| npm ci --ignore-scripts | |
| cyclonedx-npm --output-format JSON --spec-version 1.5 \ | |
| --output-file ../sbom/frontend.cdx.json | |
| - name: Generate web SBOM | |
| working-directory: web | |
| run: | | |
| npm ci --ignore-scripts | |
| cyclonedx-npm --output-format JSON --spec-version 1.5 \ | |
| --output-file ../sbom/web.cdx.json | |
| - name: SBOM summary | |
| run: | | |
| set -euo pipefail | |
| for f in sbom/*.cdx.json; do | |
| COMP=$(jq '.components | length' "$f") | |
| SPEC=$(jq -r '.specVersion' "$f") | |
| echo "$(basename "$f"): $COMP componenti (CycloneDX $SPEC)" | |
| done | |
| - name: Upload SBOMs as workflow artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: sbom-cyclonedx | |
| path: sbom/ | |
| # Retention 90 giorni e' default; per release/audit a lungo | |
| # termine vedi release.yml che li allega come release asset. | |
| retention-days: 90 |