Skip to content

Build Provenance & SLSA Attestation

Tại sao quan trọng

Khi bạn deploy image từ Artifact Registry tới production, security question:

"Who built this image, và cách nó được built?"

Nếu không có provenance:

  • No audit trail: Cannot reproduce build nếu issue discovered later
  • Supply chain risk: Malicious image có thể silently deployed
  • Compliance gap: Audit không thể verify "image built từ source code, with specific builder"

Provenance là metadata được Cloud Build generate, signed cryptographically, về:

  • Builder identity (Cloud Build service)
  • Build environment
  • Build inputs (source code, configuration)
  • Build outputs (resulting image)
  • Build timing

SLSA Framework define levels của supply chain security. Cloud Build generate SLSA Level 3 provenance (SLSA v1.0).


SLSA Framework Overview

SLSA = Supply Chain Levels for Software Artifacts. Có 4 levels:

SLSA Level 1: Low
- Source code ở version control
- Build log retained

SLSA Level 2: Increased  
- Build from version control
- Build log signed
- Build platform has basic security

SLSA Level 3: High ← Cloud Build
- Same as L2 + ephemeral builds
- Builds cannot modify inputs/outputs after completion
- Non-forgeable build identity

SLSA Level 4: Highest
- Hardened build platform
- Reproducible builds
- Two-person code review

Cloud Build achieves SLSA Level 3 because:

✓ Builds are ephemeral (cannot re-run with modified inputs)
✓ Non-forgeable builder identity (cryptographic signing)
✓ Isolated build environment (from Chapter 1)
✓ Verifiable inputs/outputs (build configuration, source, image)


Build Provenance: Cơ Chế

Provenance Format (SLSA v1.0)

Cloud Build generates provenance ở SLSA v1.0 format:

json
{
  "version": 1,
  "buildDefinition": {
    "buildType": "https://cloudbuild.googleapis.com/CloudBuild@v1",
    "externalParameters": {
      "source": {
        "uri": "git://github.com/myorg/myapp.git",
        "digest": {"sha256": "abc123..."}
      },
      "buildConfig": {
        "uri": "gs://bucket/cloudbuild.yaml"
      }
    },
    "internalParameters": {
      "projectId": "my-project",
      "buildId": "build-id-12345"
    }
  },
  "runDetails": {
    "builder": {
      "id": "https://cloudbuild.googleapis.com/cloud-build-v1"
    },
    "metadata": {
      "invocationId": "build-id-12345",
      "startedOn": "2024-01-15T10:00:00Z",
      "finishedOn": "2024-01-15T10:05:00Z"
    },
    "byproducts": [
      {
        "uri": "gcr.io/project/app@sha256:def456...",
        "digest": {"sha256": "def456..."}
      }
    ]
  }
}

Key fields:

  • buildDefinition: What was built (source, config, build type)
  • runDetails: How it was built (builder, timing, outputs)
  • All data is cryptographically signed by Cloud Build

Generation Process

1. Build triggered
2. Cloud Build records inputs
   ├─ Source code commit hash
   ├─ Build configuration (cloudbuild.yaml)
   ├─ Builder identity
   └─ Build environment
3. Build executes
4. Cloud Build records outputs
   └─ Resulting artifact (image digest)
5. Provenance generated + signed
6. Provenance stored ở Artifact Analysis

Verifying Provenance

View Provenance

bash
# View provenance metadata for image
gcloud artifacts images describe \
  us-central1-docker.pkg.dev/PROJECT/repo/app@sha256:abc123 \
  --show-provenance

# Output:
# buildDefinition:
#   buildType: https://cloudbuild.googleapis.com/CloudBuild@v1
#   externalParameters:
#     source:
#       uri: git://github.com/myorg/myapp
#       digest:
#         sha256: abc123def456...

Verify Signature

Provenance được signed với Cloud Build's private key. You can verify signature:

bash
# Check provenance signature
gcloud artifacts images describe \
  us-central1-docker.pkg.dev/PROJECT/repo/app@sha256:abc123 \
  --show-provenance \
  --format=json | \
  jq '.provenance[0].signature'

In practice: Binary Authorization (Chapter 8) automatically verifies signatures — you don't manually verify.


Real-World: Provenance + Deployment Audit Trail

Scenario

Deployment failed ở production. Investigation:

Q: Was this image built từ main branch?
A: Check provenance source hash

Q: What configuration was used?
A: Check provenance buildDefinition

Q: Who approved the deployment?
A: Check Binary Authorization policy + approval logs

Investigation

bash
# Find image being deployed
kubectl get deployment app -o jsonpath='{.spec.template.spec.containers[0].image}'
# Output: us-central1-docker.pkg.dev/PROJECT/repo/app@sha256:abc123def456

# Check provenance
gcloud artifacts images describe \
  us-central1-docker.pkg.dev/PROJECT/repo/app@sha256:abc123def456 \
  --show-provenance --format=json > provenance.json

# Verify
# - Source commit: abc123def456 (which commit is this?)
# - Build timestamp: When was it built?
# - Builder: Definitely Cloud Build? Not local docker build?

# Cross-reference git
git log --oneline | grep abc123def456
# Should match source hash ở provenance

# View build logs
gcloud builds log build-id-12345

SLSA Attestation & Binary Authorization

Provenance becomes useful when combined with attestation verification (Chapter 8):

Image deployed

Binary Authorization checks
  ├─ Is provenance present? ✓
  ├─ Is provenance signature valid? ✓
  ├─ Was image built by Cloud Build? ✓
  ├─ No CRITICAL vulnerabilities? ✓
  └─ Approved attestations? ✓

Deployment ALLOWED ✓

Without Binary Authorization, provenance exists but has no enforcement.


Cloud Build Provenance Settings

Enable/Disable Provenance

Provenance generation default enabled. To explicitly enable:

yaml
# cloudbuild.yaml
options:
  requestedVerifyOption: VERIFIED

This tells Cloud Build "I want cryptographic proof of build".

Provenance Export

Provenance stored ở Artifact Analysis (if building Docker image). Can also export to GCS:

bash
# After build completes, export provenance
gcloud builds describe BUILD_ID \
  --format=json | jq '.provenance' > provenance.json

Constraints & Considerations

Provenance Only for Cloud Build

Local docker build + docker push does NOT generate provenance.

Workaround: Always use Cloud Build untuk production builds:

bash
# ✓ Generates provenance
gcloud builds submit --config=cloudbuild.yaml

# ✗ No provenance
docker build -t image . && docker push image

Provenance Size

Provenance 约 1-2 KB per image. Negligible storage cost.

Reproducibility

SLSA doesn't guarantee reproducible builds (rebuilding with same inputs yields same output).

This requires additional effort:

  • Fixed base image versions
  • Pinned dependency versions
  • Deterministic build flags

References