Skip to content

chore(deps): bump actions/upload-artifact from 4 to 7 #264

chore(deps): bump actions/upload-artifact from 4 to 7

chore(deps): bump actions/upload-artifact from 4 to 7 #264

Workflow file for this run

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