Skip to content

Artifact Registry — Repository Model, Vulnerability Scanning & Cleanup Policies

Tại sao Artifact Registry thay thế Container Registry

Container Registry (gcr.io) là predecessor của Artifact Registry. Sự khác biệt cốt lõi không chỉ là "tên mới":

Container Registry chỉ hỗ trợ Docker images và lưu trữ trên GCS buckets backend. Mọi control là project-level IAM. Không có repository-level isolation.

Artifact Registry là artifact management platform đầy đủ: hỗ trợ Docker, npm, Python, Java, Go, Helm, Apt, RPM, và generic artifacts. IAM có thể set ở repository level (không phải chỉ project). Có built-in vulnerability scanning, cleanup policies, remote repository caching, và SLSA provenance storage.

Google đã announce Container Registry deprecated — migration sang Artifact Registry là bắt buộc.

Repository Types

Standard Repository

Repository thông thường để lưu artifacts của bạn:

bash
# Tạo Docker repository
gcloud artifacts repositories create my-docker-repo \
  --repository-format=docker \
  --location=us-central1 \
  --description="Production Docker images"

# Tạo Python repository
gcloud artifacts repositories create my-python-repo \
  --repository-format=python \
  --location=us-central1

Supported formats:

  • docker: Docker images và OCI artifacts
  • go: Go modules
  • maven: Maven/Gradle Java artifacts (JARs, WARs, POMs)
  • npm: Node.js packages
  • python: Python packages (wheels, sdist)
  • ruby: RubyGems
  • helm: Helm charts
  • apt: Debian packages
  • yum: RPM packages
  • generic: Arbitrary files

Remote Repository — Caching Upstream Sources

Remote repository proxy và cache artifacts từ upstream public sources:

bash
gcloud artifacts repositories create npm-cache \
  --repository-format=npm \
  --location=us-central1 \
  --mode=remote-repository \
  --remote-repo-config-desc="NPM Registry" \
  --remote-npm-repo=NPMJS

Upstream sources hỗ trợ:

  • Docker Hub, Quay.io, GCR, GHCR (Docker)
  • PyPI (Python)
  • npm Registry (npm)
  • Maven Central (Java)
  • Go Module Proxy

Lợi thế của Remote Repository:

  1. Build isolation: Private worker pool với NO_PUBLIC_EGRESS vẫn có thể pull packages. Traffic đến remote repository đi qua Google APIs, không cần internet.

  2. Vulnerability scanning: Artifacts được cached và scan. Detect CVEs trong dependencies.

  3. Resilience: Nếu upstream (npmjs.com, PyPI) down, builds vẫn work với cached versions.

  4. Speed: Pull từ regional Artifact Registry trong GCP nhanh hơn pull từ public registry qua internet.

yaml
# .npmrc cho npm remote repository
registry=https://us-central1-npm.pkg.dev/my-project/npm-cache/
//us-central1-npm.pkg.dev/my-project/npm-cache/:_authToken=${AR_TOKEN}

Virtual Repository — Unified Search Across Repos

Virtual repository là read-only view tổng hợp từ nhiều upstream repositories với search priority:

bash
gcloud artifacts repositories create my-virtual-docker \
  --repository-format=docker \
  --location=us-central1 \
  --mode=virtual-repository \
  --upstream-policy-file=upstreams.json
json
// upstreams.json
[
  {
    "id": "internal-repo",
    "repository": "projects/my-project/locations/us-central1/repositories/internal-docker",
    "priority": 100
  },
  {
    "id": "docker-hub-cache",
    "repository": "projects/my-project/locations/us-central1/repositories/docker-hub-remote",
    "priority": 80
  }
]

Khi pull image từ virtual repo: search internal-repo trước (priority 100), nếu không tìm thấy thì tìm trong docker-hub-cache (priority 80). Developers chỉ cần biết một URL, không biết image đến từ đâu.

Internal Architecture — Cách Artifact Registry Lưu Trữ

Regional Storage Model

Artifacts được lưu trong GCS buckets internal (không phải buckets trong project của bạn). Artifact Registry quản lý storage, bạn không direct access vào GCS.

URL format phụ thuộc format:

# Docker
REGION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG

# npm
REGION-npm.pkg.dev/PROJECT_ID/REPOSITORY/PACKAGE_NAME

# Python
REGION-python.pkg.dev/PROJECT_ID/REPOSITORY

# Maven
REGION-maven.pkg.dev/PROJECT_ID/REPOSITORY

Regional storage có nghĩa là artifacts được lưu trong một region. Để multi-region access:

  • Multi-region repositories (us, eu, asia) — artifacts được replicated tự động
  • Hoặc tạo repositories trong từng region

Authentication

Artifact Registry dùng GCP IAM authentication. Không cần .dockercfg hay username/password riêng.

bash
# Configure Docker để dùng gcloud credentials
gcloud auth configure-docker us-central1-docker.pkg.dev

# Từ đó, docker push/pull tự động authenticate
docker push us-central1-docker.pkg.dev/my-project/my-repo/myapp:latest

Cho CI/CD:

bash
# Cloud Build và GCE instances tự động authenticate qua service account
# Không cần credential config thêm nếu SA có đúng permissions

# Cho GKE, dùng imagePullSecrets hoặc Workload Identity
kubectl create secret docker-registry artifact-registry \
  --docker-server=us-central1-docker.pkg.dev \
  --docker-username=_json_key \
  --docker-password="$(cat key.json)"

Hoặc tốt hơn, dùng Workload Identity để GKE nodes tự authenticate mà không cần key.

Vulnerability Scanning — Artifact Analysis

Cơ Chế Bên Trong

Artifact Analysis là service riêng biệt nhưng tích hợp chặt với Artifact Registry. Kiến trúc dựa trên notes và occurrences:

  • Note: Template định nghĩa loại vulnerability (VD: CVE-2024-12345 ảnh hưởng đến package X versions Y-Z)
  • Occurrence: Instance của note áp dụng lên artifact cụ thể (VD: image my-app:1.0.0 chứa package X version Y, affected bởi CVE-2024-12345)

Notes được quản lý bởi Google (CVE database được update liên tục). Occurrences được tạo khi scan artifact.

On-Push Scanning (Automatic)

Khi push Docker image vào Artifact Registry, scan được triggered tự động:

docker push us-docker.pkg.dev/my-project/my-repo/myapp:1.0.0

Artifact Registry nhận image

Artifact Analysis starts scanning:
  1. Extract OS packages (dpkg, rpm, apk)
  2. Extract language packages (pip, npm, gem, maven, go)
  3. Match against Google's vulnerability database

Scan results stored as Occurrences

Vulnerability data liên tục được cập nhật khi new CVEs discovered
(không cần re-push image)

Continuous Scanning: Đây là điểm quan trọng. Sau khi image được scan, Artifact Analysis tiếp tục monitor vulnerability database. Khi CVE mới được published ảnh hưởng đến packages trong image, Artifact Analysis tự động tạo mới occurrences — không cần push image lại.

Điều này có nghĩa là một image push 6 tháng trước có thể có vulnerability mới hôm nay, và Artifact Registry sẽ reflect điều đó.

On-Demand Scanning

Scan image mà không cần push (VD: scan trước khi push):

bash
# Scan local image
gcloud artifacts docker images scan my-app:local \
  --format='value(response.scan)'

# Scan remote image
gcloud artifacts docker images scan \
  us-docker.pkg.dev/my-project/my-repo/myapp:1.0.0 \
  --remote \
  --format=json

On-demand scan results có giá trị 48 giờ và không liên tục cập nhật. Phù hợp cho scanning trước khi push trong CI/CD gate.

Đọc Scan Results

bash
# Liệt kê vulnerabilities của một image
gcloud artifacts docker images list-vulnerabilities \
  us-docker.pkg.dev/my-project/my-repo/myapp@sha256:abc123... \
  --format='table(vulnerability.packageIssue[0].affectedPackage, vulnerability.severity, vulnerability.fixedPackage)'

Tích hợp với Binary Authorization để block deployment nếu image có vulnerabilities:

  • Attestor check vulnerability scan kết quả
  • Policy require attestation "no critical vulnerabilities"
  • Deploy bị block nếu attestation không có hoặc vulnerabilities tồn tại

SBOM Generation

SBOM (Software Bill of Materials) là danh sách tất cả components trong một artifact — OS packages, language dependencies, licenses.

bash
# Export SBOM cho image
gcloud artifacts sbom export \
  --uri=us-docker.pkg.dev/my-project/my-repo/myapp@sha256:abc123 \
  --destination=sbom.json

# Format SPDX 2.3 hoặc CycloneDX 1.4
gcloud artifacts sbom export \
  --uri=... \
  --sbom-format=CYCLONE_DX_1_4 \
  --destination=sbom-cyclonedx.json

SBOM được lưu như Artifact Analysis occurrence, có thể truy vấn:

bash
# List SBOM occurrences cho artifact
gcloud artifacts docker images describe \
  us-docker.pkg.dev/my-project/my-repo/myapp:1.0.0 \
  --show-provenance \
  --show-sbom

SBOM quan trọng cho:

  • Compliance (NIST SSDF, EO 14028 về software supply chain security)
  • License audit (phát hiện copyleft licenses)
  • Truy vết khi CVE mới công bố ảnh hưởng component cụ thể

Cleanup Policies — Quản Lý Artifact Lifecycle

Không có cleanup policy, repositories có thể grow vô tớ, gây cost storage và confusion.

Policy Types

Delete Policy: Xóa artifacts theo điều kiện

json
{
  "name": "delete-old-untagged",
  "action": {"type": "Delete"},
  "condition": {
    "tagState": "UNTAGGED",
    "olderThan": "7d"
  }
}

Conditional Keep Policy: Retain artifacts matching conditions, override delete policies

json
{
  "name": "keep-release-tags",
  "action": {"type": "Keep"},
  "condition": {
    "tagPrefixes": ["v", "release-"],
    "tagState": "TAGGED"
  }
}

Keep Most Recent Versions:

json
{
  "name": "keep-10-latest",
  "action": {
    "type": "Keep",
    "mostRecentVersions": {
      "packageNamePrefixes": [],
      "keepCount": 10
    }
  }
}

Policy Evaluation Logic

Khi nhiều policies áp dụng cho một artifact:

  1. Chạy tất cả delete policies
  2. Chạy tất cả keep policies
  3. Nếu bất kỳ keep policy nào match → artifact được giữ (bất kể delete policy)
  4. Nếu bất kỳ delete policy nào match VÀ không có keep policy nào match → artifact bị xóa
  5. Nếu không policy nào match → artifact được giữ (mặc định an toàn)

Background execution: Cleanup chạy như background jobs, không real-time. Có thể cần đến 1 ngày để effects có hiệu lực. Dry-run trước:

bash
gcloud artifacts repositories set-cleanup-policies my-docker-repo \
  --project=my-project \
  --location=us-central1 \
  --policy=cleanup-policy.json \
  --dry-run  # Xem artifacts nào sẽ bị xóa, không thực sự xóa

Immutable Tags

Tag immutability ngăn overwrite tags:

bash
gcloud artifacts repositories update my-docker-repo \
  --location=us-central1 \
  --tag-immutability  # Tags không thể overwrite

Khi tag immutability bật:

  • docker push myapp:v1.0.0 lần đầu: thành công
  • docker push myapp:v1.0.0 lần hai (image khác): 403 Forbidden
  • Cleanup policies không xóa được tagged artifacts với immutable tags

Immutable tags là best practice cho production releases — đảm bảo v1.0.0 luôn là cùng một image.

IAM Model — Repository-Level Permissions

Artifact Registry support IAM ở hai levels:

Project-Level IAM (Apply cho tất cả repos)

bash
# Grant role cho toàn bộ project
gcloud projects add-iam-policy-binding my-project \
  --member=serviceAccount:ci-builder@my-project.iam.gserviceaccount.com \
  --role=roles/artifactregistry.writer

Repository-Level IAM (Granular)

bash
# Grant role cho một repository cụ thể
gcloud artifacts repositories add-iam-policy-binding my-docker-repo \
  --location=us-central1 \
  --member=serviceAccount:ci-builder@my-project.iam.gserviceaccount.com \
  --role=roles/artifactregistry.writer

# Developer read-only cho prod repo
gcloud artifacts repositories add-iam-policy-binding prod-docker-repo \
  --location=us-central1 \
  --member=group:developers@company.com \
  --role=roles/artifactregistry.reader

Predefined Roles:

  • roles/artifactregistry.reader: Pull/download artifacts
  • roles/artifactregistry.writer: Push artifacts (không delete, không manage repo)
  • roles/artifactregistry.repoAdmin: Full control của repository content
  • roles/artifactregistry.admin: Full control bao gồm repo settings, IAM

Pattern khuyến nghị:

  • CI/CD SA: writer trên specific repositories
  • GKE node SA (hoặc via Workload Identity): reader
  • Platform team: repoAdmin trên repos của team
  • Service teams: reader trên external repos, writer trên repo của team

VPC Service Controls Integration

Khi Artifact Registry trong VPC-SC perimeter, chỉ requests từ trong perimeter mới có thể access:

bash
# Dùng restricted VIP cho Artifact Registry (không qua internet)
# Trong /etc/hosts hoặc DNS:
# pkg.dev → 199.36.153.4 (restricted.googleapis.com)

Với Private Worker Pool (NO_PUBLIC_EGRESS), builds vẫn có thể access Artifact Registry qua Google APIs (restricted.googleapis.com) — không cần internet, không cần tắt NO_PUBLIC_EGRESS.

References