Skip to content

Container Vulnerability Scanning & SBOM

Tại sao quan trọng

Bạn push image tới registry. Nhưng có bao nhiêu phần mềm vulnerabilities trong đó? Nếu không biết:

  • Supply chain risk: Vulnerable base image deploy tới production
  • Compliance failure: Audit tìm vulnerabilities không được remediated
  • Security incident: Compromise qua known CVE ở dependency

Artifact Analysis tự động scan containers ở Artifact Registry cho known vulnerabilities. Nó cũng generate SBOM (Software Bill of Materials) — danh sách tất cả dependencies trong image.


Vulnerability Scanning: Cơ Chế

On-Push Scanning

Khi bạn push image tới Artifact Registry:

bash
docker push us-central1-docker.pkg.dev/PROJECT_ID/docker-repo/app:latest

Cloud Build:

  1. Pushes image layers to Artifact Registry
  2. Registry triggers Artifact Analysis
  3. Artifact Analysis scans image immediately (on-push)
  4. Generates vulnerability report

Scanning process:

Image pushed

Extract layers

Identify base image (ubuntu:22.04, etc.)

Identify packages (apt packages, pip packages, npm packages)

Cross-reference với known vulnerability databases
  ├─ Google's CVE database
  ├─ NVD (National Vulnerability Database)
  └─ Vendor-specific advisories

Generate vulnerability report
  ├─ Critical vulnerabilities
  ├─ High severity
  ├─ Medium severity
  └─ Low severity

Continuous Scanning

Nếu new vulnerability discovered sau push, Artifact Analysis automatically updates metadata:

Timeline:
- Day 1: Push image with package-xyz:1.0
  → No vulnerabilities found
  
- Day 30: New CVE-2024-XXXXX discovered
  → Artifact Analysis sees CVE affects package-xyz:1.0
  → Automatically update image metadata: VULNERABLE
  
- Binary Authorization checks:
  → Image marked VULNERABLE
  → Deployment BLOCKED

This protects against supply chain attacks — vulnerabilities discovered later ở existing images.


SBOM (Software Bill of Materials)

What is SBOM?

SBOM là structured list của tất cả dependencies ở container image:

json
{
  "image": "us-central1-docker.pkg.dev/PROJECT/docker-repo/app:latest",
  "components": [
    {
      "name": "ubuntu",
      "version": "22.04",
      "type": "base-image",
      "cpe": "cpe:2.3:o:canonical:ubuntu:22.04:*:*:*:*:*:*:*"
    },
    {
      "name": "openssl",
      "version": "3.0.2",
      "type": "system-package",
      "cpe": "cpe:2.3:a:openssl:openssl:3.0.2:*:*:*:*:*:*:*"
    },
    {
      "name": "node",
      "version": "18.16.0",
      "type": "tool"
    },
    {
      "name": "express",
      "version": "4.18.2",
      "type": "application-dependency",
      "cpe": "cpe:2.3:a:expressjs:express:4.18.2:*:*:*:*:*:*:*"
    }
  ]
}

Generating SBOM

Automatic:

bash
# Enable Container Scanning API (usually automatic with Artifact Registry)
gcloud services enable containerscanning.googleapis.com

# Push image
docker push us-central1-docker.pkg.dev/PROJECT_ID/repo/app:latest

# SBOM automatically generated by Artifact Analysis

Retrieve SBOM:

bash
gcloud artifacts sbom export \
  --image=us-central1-docker.pkg.dev/PROJECT_ID/repo/app:latest \
  --format=json

SBOM Formats

Artifact Analysis supports:

  • SPDX (Software Package Data Exchange): Industry standard
  • CycloneDX: XML/JSON format
  • Syft: Anchore's format

SBOM Use Cases

  1. Compliance/Audit: "Show me all software ở image"
  2. Vulnerability correlation: Given list của known vulnerable packages, check which images affected
  3. License management: Extract licenses từ dependencies
  4. Supply chain attestation: SBOM signed và included ở build provenance

Artifact Cleanup Policies

Why Cleanup?

Scenario: Build 10x per day, each creates ~500 MB image

Per month: 10 builds/day * 30 days = 300 builds = 150 GB storage
Cost: 150 GB * $0.026/month = $3.90/month

Over time: Builds accumulate, storage fills, costs grow

Cleanup policies automatically delete old images per retention rules.

Cleanup Policy Configuration

bash
gcloud artifacts repositories create docker-prod \
  --repository-format=docker \
  --location=us-central1 \
  --cleanup-policy-delete=30d  # Delete images older than 30 days

Or update existing:

bash
gcloud artifacts repositories update docker-prod \
  --location=us-central1 \
  --cleanup-policy-delete=7d  # Keep only 7 days of images

Cleanup Policy Rules

bash
gcloud artifacts repositories create docker-dev \
  --repository-format=docker \
  --location=us-central1

# Add cleanup rule: delete images older than 7 days
gcloud artifacts repositories create rules docker-dev \
  --repository=docker-dev \
  --location=us-central1 \
  --condition-tag-state=ANY \
  --condition-newer-than=7d \
  --action=DELETE

Protection Rules (Prevent Deletion)

Nếu bạn muốn protect specific images từ deletion:

bash
# Protect production images
gcloud artifacts repositories add-iam-policy-binding docker-prod \
  --location=us-central1 \
  --member=serviceAccount:cleanup-job@PROJECT.iam.gserviceaccount.com \
  --role=roles/artifactregistry.writer

# Then in cleanup policy, exclude production images
gcloud artifacts repositories create rules docker-prod \
  --repository=docker-prod \
  --location=us-central1 \
  --condition-tag-state='TAGGED'  # Only delete untagged images
  --action=DELETE

Real-World Cleanup Strategy

yaml
# Keep strategy
- Production images (tagged with 'prod'): Never delete
- Staging images (tagged with 'staging'): Keep 30 days
- Dev images (tagged with 'dev' or untagged): Keep 7 days

# Implementation
gcloud artifacts repositories create cleanup-rules docker-prod \
  --repository=docker-prod \
  --location=us-central1

# Rule 1: Delete dev images older than 7 days
gcloud artifacts repositories create rules dev-cleanup \
  --repository=docker-prod \
  --location=us-central1 \
  --condition-tag-state=TAGGED \
  --condition-tag-name='dev' \
  --condition-newer-than=7d \
  --action=DELETE

# Rule 2: Delete untagged images older than 7 days
gcloud artifacts repositories create rules untagged-cleanup \
  --repository=docker-prod \
  --location=us-central1 \
  --condition-tag-state=UNTAGGED \
  --condition-newer-than=7d \
  --action=DELETE

Binary Authorization Integration

Artifact Analysis kết hợp với Binary Authorization để block deployments:

Container pushed

Artifact Analysis scans

Report: CRITICAL vulnerability found

Binary Authorization checks

BLOCK deployment
  (only allow deployment nếu vulnerabilities remediated)

More details ở Chapter 8.


Real-World Scenario: Zero-Trust Container Security

Requirements

  1. All images scanned — automatic, on-push
  2. SBOM generated — audit trail
  3. Old images deleted — cost optimization
  4. Critical vulnerabilities block deployment — security gate

Setup

1. Enable Container Scanning:

bash
gcloud services enable containerscanning.googleapis.com

2. Cloud Build pushes image:

yaml
steps:
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'build'
      - '-t'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/docker-prod/app:$SHORT_SHA'
      - '.'
  
  - name: 'gcr.io/cloud-builders/docker'
    args:
      - 'push'
      - 'us-central1-docker.pkg.dev/$PROJECT_ID/docker-prod/app:$SHORT_SHA'
      # Automatic: Artifact Analysis scans upon push

3. Scan status monitored:

bash
gcloud artifacts images describe us-central1-docker.pkg.dev/$PROJECT_ID/docker-prod/app:$SHORT_SHA \
  --show-package-vulnerability

# Output:
# imageUrl: ...
# vulnerabilities:
#   - cve: CVE-2024-12345
#     severity: CRITICAL
#     package: openssl
#     fixed_version: 3.0.12

4. SBOM extracted:

bash
gcloud artifacts sbom export \
  --image=us-central1-docker.pkg.dev/$PROJECT_ID/docker-prod/app:$SHORT_SHA \
  --format=cyclonedx-json > sbom.json

5. Cleanup policy:

bash
gcloud artifacts repositories create cleanup-rules docker-prod \
  --repository=docker-prod \
  --location=us-central1 \
  --condition-newer-than=30d \
  --action=DELETE

6. Binary Authorization enforces (Chapter 8):

bash
gcloud container binauthz policy create policy.yaml
# Policy blocks images with CRITICAL vulnerabilities

Constraints & Failure Modes

Scanning Takes Time

On-push scanning може take 1-5 minutes. Image immediately available, but vulnerability report appears after.

If you need immediate scan status:

bash
gcloud artifacts images describe us-central1-docker.pkg.dev/PROJECT/repo/image \
  --show-package-vulnerability \
  --wait-for-scan

False Positives in Scanning

Scanning sometimes reports vulnerabilities that don't affect you:

  • Vulnerability ở library, but code path never called
  • Vulnerability requires specific OS configuration

Mitigation:

  • Use Artifact Analysis custom policies (exclude specific CVEs per project)
  • Implement "vulnerability exception" process ở organization level

SBOM Missing Dependencies

SBOM sometimes misses transitive dependencies (e.g., npm sub-dependencies).

More accurate SBOM:

Include build-time SBOM generation ở Dockerfile:

dockerfile
FROM ubuntu:22.04

# Install syft (SBOM generator)
RUN apt-get update && apt-get install -y curl && \
    curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh

# Generate SBOM during build
RUN syft packages alpine:latest -o json > /sbom.json

# Copy SBOM to image
COPY --from=syft /sbom.json /sbom.json

References