Skip to content

CVE Scanning

Every image PaaS Runtime builds is scanned by Trivy for known vulnerabilities. Tenants see the full CVE list in the dashboard, can re-scan on demand, and may opt into a hard "block-deploy-on-CRITICAL" policy via paas.toml.

Pipeline

sequenceDiagram
  participant K as Kaniko / Paketo
  participant T as Trivy
  participant CP as Control Plane
  participant DB as Postgres (build_security_scans)
  participant U as Tenant

  K->>T: image push complete
  T->>T: trivy image --severity CRITICAL,HIGH --format json
  T->>CP: POST /internal/v1/builds/{build_id}/security-scan
  CP->>DB: UPSERT row (build_id, app_id, counts, report_jsonb)
  U->>CP: GET /v1/apps/{app_id}/security/scans/latest
  CP->>DB: SELECT latest WHERE app_id ORDER BY scanned_at DESC
  CP-->>U: ScanSummary {critical, high, medium, low, report}

The Trivy Task lives in the paas-build Kubernetes namespace and is referenced by both the Paketo (paas-build-pipeline) and Dockerfile (paas-dockerfile-pipeline) pipelines. A shared trivy-db-cache PVC keeps the vulnerability database warm across builds.

Severity levels

Level Action Recommended for HDS / SecNumCloud
CRITICAL Pipeline fails (block-on-critical default) Block deploy until fixed
HIGH Reported in dashboard, build proceeds Triage within 7 days
MEDIUM Reported only Track, fix in next release
LOW Reported only Informational

CRITICAL vulnerabilities block the PipelineRun by default (block-on-critical=true) — the Trivy step exits 1 and the image never gets the success label. Set block-on-critical=false in the PipelineRun params if you need to ship a known-bad image temporarily (strongly discouraged).

Block-deploy policy via paas.toml

Opt into a stricter policy on top of the pipeline-level CRITICAL gate:

[security]
block_deploy_on = "critical"   # or "high" or "none" (default)

When set, the control plane refuses to start a new deploy if the latest scan for the app exceeds the threshold — even if the build itself succeeded. This catches cases where a CVE is published after the image was built (vulnerable image is now sitting in Harbor).

block_deploy_on Behaviour
"none" (default) Never block — operator decides
"critical" Block deploy if latest scan reports ≥1 CRITICAL
"high" Block deploy if latest scan reports ≥1 HIGH or worse

Enforcement happens in the control plane's trigger_build handler, which has the DB context to fetch the latest scan; the build planner crate stays storage-agnostic.

Re-scan an image manually

Useful when a CVE database update lands and you want to know whether your running image is affected without redeploying:

TOKEN=$(curl -sf -X POST https://runtime.di2amp.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"you@example.com","password":"…"}' | jq -r '.data.access_token')

curl -sf -X POST \
  -H "Authorization: Bearer $TOKEN" \
  "https://runtime.di2amp.com/api/v1/apps/$APP_ID/security/scans"

Response (HTTP 202 Accepted):

{
  "data": {
    "status": "queued",
    "message": "Re-scan scheduled (Phase 2 — cron job will pick this up)"
  }
}

Cycle 2 note — the re-scan endpoint is currently a stub. A Phase 2 cron job triggers a scan-only Tekton TaskRun for the app's latest image. Calling the endpoint today queues the request; the dashboard's "Re-scan now" button uses this contract so the UI is ready when Phase 2 ships.

API endpoints

Method Path Auth Description
GET /v1/apps/{app_id}/security/scans/latest JWT Latest scan for the app (404 if never scanned)
POST /v1/apps/{app_id}/security/scans JWT Queue a re-scan (202 stub, Phase 2)
POST /internal/v1/builds/{build_id}/security-scan internal Tekton-only ingest (no JWT, K8s service network)

The supply-chain trio

CVE scanning closes the loop on the platform's supply-chain story:

  1. Supply Chain Attestation — every image gets an SBOM (CycloneDX 1.4) and a cosign signature with provenance annotations (tenant, app, commit, build).
  2. CVE Scanning (this page) — every image is scanned at build time and on demand; results are persisted and surfaced in the dashboard.
  3. Block-deploy policy — tenants can refuse to ship images whose CVE profile crosses a threshold without a manual override.

This trio gives French / EU regulated workloads (HDS, SecNumCloud, ANSSI guidance) provable answers to what was built, who built it, and what's wrong with it right now — without leaking metadata to external SaaS scanners.

Compliance summary

Standard What we provide
GDPR Zero external telemetry — Trivy scans run inside the tenant cluster
HDS / SecNumCloud CRITICAL block-on-deploy + on-prem CVE database
ANSSI SBOM + signed provenance + scan history per image
SLSA L2 Signed build provenance with attestation predicate (cycle AB/11)