Skip to main content

Scan images for vulnerabilities

This guide explains how to configure and use vulnerability scanning in the Numspot Container Registry.


Overview

The Numspot Container Registry integrates a vulnerability scan based on Trivy, allowing you to:

  • Detect CVEs: identify known vulnerabilities in container images
  • Apply security policies: block vulnerable images at deployment
  • Meet compliance requirements: comply with security requirements for production deployments
  • Continuous monitoring: scan images on push and on a schedule

Key features

  • Automatic scan: scan images automatically on push
  • Multiple scanners: Trivy (default), and support for external scanners
  • CVE database: up-to-date vulnerability database
  • Severity classification: CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN
  • Policy enforcement: prevent the deployment of vulnerable images
  • SBOM generation: Software Bill of Materials for supply chain security
  • Scan reports: detailed reports with remediation guidance

How vulnerability scanning works

Scan architecture

┌──────────────────────────────────────────────────────────┐
│ Instance Container Registry │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Image │ │ Trivy │ │ Scan │ │
│ │ push │──▶│ Adapter │──▶│ Engine │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ CVE Database │ │
│ │ │ │
│ └──────────────────┘ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Scan report │ │
│ │ (Results) │ │
│ └──────────────────┘ │
└──────────────────────────────────────────────────────────┘

Scan triggers

TriggerDescription
On pushAutomatic scan when an image is pushed
ManualTrigger a scan through the interface or the API
ScheduledPeriodic rescan (daily, weekly)
On demandScans triggered through the API

Prerequisites

  • Container Registry instance: a running Numspot Container Registry
  • Administrator or project administrator access: required to configure the scan
  • Trivy scanner: enabled by default in Numspot registries

Step 1: Configure the scan settings

Through the Harbor interface

  1. Log in to the Harbor interface as a system administrator
  2. Navigate to AdministrationInterrogation ServicesScanners
  3. Configure the Trivy scanner:
SettingValue
NameTrivy
ProviderAqua Security
DescriptionTrivy vulnerability scanner
URLhttp://harbor-trivy:8080
Auth typeAucun (internal)
  1. Click Set as default to make Trivy the default scanner

Project-level scan configuration

  1. Navigate to Projects → Select the project → Configuration
  2. Configure the scan:
SettingValue
Automatically scan images on pushEnable
Prevent vulnerable images from runningEnable (optional)
SeveritySelect the severity levels to block
Stop pulling images with CVE exemptionsConfigure as needed

Through the API

curl -X PUT "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/scanner" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"is_default_scanner": true,
"use_project_scanner": false
}'

# Enable automatic scan on push
curl -X PUT "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"auto_scan": "true"
}
}'

Step 2: Scan the images

Automatic scan on push

When automatic scan is enabled:

  1. Push an image:
docker push registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/myproject/myimage:v1.0
  1. Harbor automatically triggers a Trivy scan
  2. The scan completes within a few seconds to a few minutes (depending on the image size)

Manual scan

Through the Harbor interface

  1. Navigate to Projects → Select the project → Repositories
  2. Click the repository
  3. Click the artifact tag
  4. Click the Scan button
  5. Select the scanner: Trivy
  6. Wait for the scan to finish
  7. Review the scan results

Through the API

curl -X POST "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/scan" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"scan_type": "vulnerability"
}'

Scheduled scan

Configure periodic rescans:

  1. Navigate to AdministrationInterrogation ServicesScanners
  2. Click Schedule for the Trivy scanner
  3. Configure the cron schedule:
0 2 * * * # Daily at 2 a.m.
0 2 * * 0 # Weekly on Sunday

Step 3: Review the scan results

Through the Harbor interface

  1. Navigate to the repository and the artifact
  2. Review the Vulnerabilities tab
  3. View:
  • Total vulnerabilities: count by severity
  • Summary: CRITICAL, HIGH, MEDIUM, LOW, UNKNOWN
  • Vulnerability list: detailed information on the CVEs
  • Package information: affected package and version
  • Fixed version: remediation guidance

Vulnerability details

FieldDescription
CVE IDCVE identifier (e.g. CVE-2023-12345)
SeverityCRITICAL, HIGH, MEDIUM, LOW, UNKNOWN
PackageName of the affected package
VersionInstalled version
Fixed versionVersion with the fix (if available)
DescriptionDescription of the vulnerability
LinksReferences to the CVE details

Through the API

# Get the scan report
curl -X GET "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/scan" \
-u "admin:{password}"

# Get the vulnerability summary
curl -X GET "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/additions/vulnerabilities" \
-u "admin:{password}" | jq '.scan_overview'

Response:

{
"scan_overview": {
"application/vnd.scanner.adapter.vuln.report.harbor+json; version=1.0": {
"report_id": "abc123",
"scan_status": "Success",
"severity": "HIGH",
"duration": 45,
"summary": {
"total": 25,
"fixable": 18,
"summary": {
"CRITICAL": 2,
"HIGH": 8,
"MEDIUM": 10,
"LOW": 5,
"UNKNOWN": 0
}
},
"start_time": "2026-05-05T10:00:00Z",
"end_time": "2026-05-05T10:00:45Z"
}
}
}

Step 4: Apply security policies

Prevent vulnerable images from running

Block images with vulnerabilities above a threshold:

  1. Navigate to Projects → Select the project → Configuration
  2. Enable Prevent vulnerable images from running
  3. Select the severity levels to block:
  • CRITICAL (recommended)
  • HIGH (recommended)
  • MEDIUM (optional)
  • LOW (optional)

Once enabled:

  • images with vulnerabilities at the selected levels or higher cannot be pulled
  • Harbor returns 403 Forbidden for vulnerable images
  • the scan must be completed before the image can be pulled

Through the API

curl -X PUT "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"metadata": {
"auto_scan": "true",
"prevent_vul": "true",
"severity": "high,critical"
}
}'

CVE allowlist

Allow specific CVEs to permit images with known exceptions:

  1. Navigate to AdministrationConfigurationSystem Settings
  2. Scroll to CVE Allowlist
  3. Add the CVE IDs to allow:
CVE-2023-12345
CVE-2023-67890
  1. Click Save

Through the API

curl -X PUT "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/system/CVEWhitelist" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"items": [
{"cve_id": "CVE-2023-12345"},
{"cve_id": "CVE-2023-67890"}
]
}'

Severity classification

SeverityDescriptionRecommendation
CRITICALExploitable, immediate riskFix immediately
HIGHSignificant risk, prioritize the fixFix in the next release
MEDIUMModerate risk, should be fixedFix when possible
LOWMinor risk, informationalAssess the impact
UNKNOWNInsufficient data to classifyInvestigate further

Best practices

Scan strategy

  1. Enable automatic scan: scan on every push
  2. Block critical vulnerabilities: prevent the deployment of CRITICAL and HIGH
  3. Regular rescans: schedule weekly scans for the updated CVE databases
  4. Scan base images: ensure that base images are free of vulnerabilities
  5. Validate before production: scan in staging before promotion to production

Remediation flow

  1. Identify the vulnerabilities: review the scan report
  2. Prioritize the fixes: focus on CRITICAL and HIGH first
  3. Update the packages: upgrade to the fixed versions
  4. Verify the fixes: rescan after remediation
  5. Document the exceptions: use the CVE allowlist for accepted risks

CI/CD integration

Integrate vulnerability scanning into your CI/CD pipeline:

# GitLab CI example
scan-image:
stage: security
image: docker:latest
services:
- docker:dind
script:
- docker login -u "$HARBOR_USER" -p "$HARBOR_PASSWORD" $HARBOR_REGISTRY
- docker pull $HARBOR_REGISTRY/myproject/myimage:$CI_COMMIT_SHA
- |
SCAN_RESULT=$(curl -s -u "$HARBOR_USER:$HARBOR_PASSWORD" \
"$HARBOR_REGISTRY/api/v2.0/projects/myproject/repositories/myimage/artifacts/$CI_COMMIT_SHA/scan" | jq -r '.scan_overview[].severity')
if [ "$SCAN_RESULT" == "CRITICAL" ] || [ "$SCAN_RESULT" == "HIGH" ]; then
echo "Vulnerabilities detected: $SCAN_RESULT"
exit 1
fi
allow_failure: false

Advanced features

SBOM generation

Generate a Software Bill of Materials:

  1. Navigate to the artifact details
  2. Click the SBOM tab
  3. View the packages and dependencies
  4. Export the SBOM in SPDX or CycloneDX format

Through the API

curl -X POST "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/scan" \
-u "admin:{password}" \
-H "Content-Type: application/json" \
-d '{
"scan_type": "sbom"
}'

Trivy configuration

Trivy configuration options:

SettingDescriptionDefault value
Skip updateSkip the update of the CVE databasefalse
Offline scanUse the cached databasefalse
SeverityMinimum severity to reportUNKNOWN
Ignore unfixedIgnore vulnerabilities without a fixfalse

Monitoring and reporting

Scan metrics

Monitor scan performance:

  1. Navigate to AdministrationMetrics
  2. Review the scan metrics:
  • total images scanned
  • vulnerabilities detected by severity
  • scan duration trends
  • scanner queue length

Security dashboard

View the security posture:

  1. Navigate to AdministrationSecurity Hub
  2. Review:
  • vulnerability summary per project
  • most vulnerable images
  • most common CVEs
  • security trends over time

Export reports

Export the vulnerability reports:

# Get all vulnerabilities for an artifact
curl -X GET "https://registry-{registryId}.hcp.cloudgouv-eu-west-1.numspot.com/api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/additions/vulnerabilities" \
-u "admin:{password}" > rapport-vulnerabilites.json

Troubleshooting

Issue 1: Scan timeout

Symptom: the scan takes too long or times out

Solutions:

  1. Increase the scanner timeout:
kubectl patch deployment harbor-trivy -n registry-instance-{registryId} --type=json -p='[{"op": "add", "path": "/spec/template/spec/containers/0/env/-", "value": {"name": "SCANNER_TIMEOUT", "value": "10m"}}]'
  1. Check the Trivy pod resources
  2. Check the network connectivity to the CVE database
  3. Consider scanning smaller images

Issue 2: Scanner unavailable

Symptom: scans fail with scanner unavailable

Solutions:

  1. Check the status of the Trivy pod:
kubectl get pods -n registry-instance-{registryId} | grep trivy
  1. Review the Trivy pod logs:
kubectl logs -n registry-instance-{registryId} deployment/harbor-trivy
  1. Contact Numspot support

Issue 3: Outdated CVE database

Symptom: CVEs not detected or outdated

Solutions:

  1. Trigger the update of the Trivy database:
kubectl rollout restart deployment/harbor-trivy -n registry-instance-{registryId}
  1. Wait for the database update to complete
  2. Rescan the affected images

Issue 4: False positives

Symptom: CVEs incorrectly reported

Solutions:

  1. Verify the applicability of the CVE to your use case
  2. Add the CVEs to the allowlist if the risk is accepted
  3. Document the justification for the acceptance
  4. Report the false positives to the Trivy project

API reference

Trigger a scan

POST /api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/scan
Authorization: Basic {base64(admin:password)}
Content-Type: application/json

{
"scan_type": "vulnerability | sbom"
}

Get the scan report

GET /api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/scan
Authorization: Basic {base64(admin:password)}

Get the vulnerability details

GET /api/v2.0/projects/{project_id}/repositories/{repository_name}/artifacts/{digest}/additions/vulnerabilities
Authorization: Basic {base64(admin:password)}

Update the project scan settings

PUT /api/v2.0/projects/{project_id}
Authorization: Basic {base64(admin:password)}
Content-Type: application/json

{
"metadata": {
"auto_scan": "true",
"prevent_vul": "true",
"severity": "high,critical"
}
}

Limitations

  • File system scan only: Trivy scans the file system, not running containers
  • Licensed software: may not detect vulnerabilities in proprietary software
  • CVE database lag: new CVEs may not be immediately available
  • False negatives: some vulnerabilities may not be detected
  • Resource-intensive: large images require more scan time and resources