Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/actions/build-reference-values/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: Build reference values
description: Checkout, install tooling, verify upstream attestations, and build results/reference-values.json
runs:
using: composite
steps:
- name: Setup Python
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
python-version: "3.12"

- name: Install dependencies
shell: bash
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt

- uses: oras-project/setup-oras@38de303aac69abb66f3e6255b7198bff35f323e3 # v2.0.0
with:
version: "1.3.1"

- name: Verify upstream artifact attestations
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
python3 reference_values.py verify versions.yaml

- name: Build reference values JSON
shell: bash
run: |
mkdir -p results
python3 reference_values.py build versions.yaml results/reference-values.json
68 changes: 68 additions & 0 deletions .github/workflows/reference-values.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
name: Build Reference Values For CoCo Release

on:
pull_request:
release:
types: [published]

jobs:
build-reference-values-pr:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
permissions:
contents: read

Comment thread
Xynnn007 marked this conversation as resolved.
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: ./.github/actions/build-reference-values

build-reference-values-release:
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: read
actions: write
Comment thread
Xynnn007 marked this conversation as resolved.

steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2

- uses: ./.github/actions/build-reference-values

- name: Upload reference values for release job
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: reference-values-json
path: results/reference-values.json

publish-release:
needs: build-reference-values-release
if: github.event_name == 'release'
runs-on: ubuntu-latest
permissions:
contents: write
actions: read
id-token: write
attestations: write
artifact-metadata: write

steps:
- name: Download reference values JSON
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: reference-values-json
path: results

- name: Release Reference Values JSON
uses: softprops/action-gh-release@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # v3.0.0
with:
files: |
results/reference-values.json

- name: Generate SLSA provenance attestation
id: attest_provenance
uses: actions/attest@59d89421af93a897026c735860bf21b6eb4f7b26 # v4.1.0
with:
subject-path: results/reference-values.json
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
__pycache__/
results/
.work
123 changes: 123 additions & 0 deletions DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
# Development Guide

This document covers repository layout, configuration, and how to add or change measurement plugins.

## Repository layout

```text
reference_values.py # CLI: verify | build | update-digests
internal/ # Python helpers (not a published package)
config.py # Load / validate / write YAML
workspace.py # Git clone, oras pull, run measurements/*.sh
commands.py # verify, build, update-digests implementations
measurements/ # One shell plugin per reference value
scripts/ # verify-provenance.sh
arch/ # Per-platform OCI digests + RV URIs
versions.yaml # CoCo version, Kata pins, git tool pins
```

YAML pins *what* to use (versions, digests, URIs). Shell plugins in `measurements/` define *how* to measure.

## Configuration

### `versions.yaml`

- `version` — CoCo release version (used in output JSON keys)
- `kata` — OCI registry and attestation metadata for upstream verification (`revision` is the authoritative pin; release tag can be kept as a comment)
- `git` — external tool repos (`url` + `digest`); cloned to `.work/git/<key>/` before plugins run
- `reference_values_files` — list of arch-specific YAML files to merge

### `arch/*.yaml`

Each `reference_values` entry includes:

- `name` — stable identifier for logs and extract paths (need not match the script filename)
- `measurement_script` — filename under `measurements/` (e.g. `tdx-kernel.sh`)
- `reference_value_uri` — RVPS URI prefix for the output key
- `artifacts` — list of the materials to derive this reference value `{ name, oci_sha256 }`
- optional `description`, `arch`

## Adding a reference value

1. Add an entry in `arch/<platform>.yaml` with `name`, `measurement_script`, `reference_value_uri`, and pinned `artifacts`.
2. Add an executable `measurements/<measurement_script>` whose **stdout** is the reference value as hex only: no trailing newline, no `0x` prefix, and no other text. Send logs and diagnostics to **stderr** (they are not stored).
3. If the measurement needs a new external repo, add it under `git:` in `versions.yaml` (`url` + commit `digest`).

The build step reads plugin stdout and applies `.strip()` before writing JSON, so a trailing newline is tolerated but must not be relied on—plugins should emit exactly the hex string.

Example plugin (see also `measurements/tdx-kernel.sh`):

```bash
#!/usr/bin/env bash
set -euo pipefail

CALC="${GIT_TD_SHIM_ROOT}/td-shim-tools/src/bin/td-payload-reference-calculator/td_payload_qemu_hash.py"
python3 "${CALC}" -k "./opt/kata/share/kata-containers/vmlinuz.container"
```

Use paths **inside the cloned git repo** in the plugin; do not list tool file paths in `versions.yaml`.

Example arch entry:

```yaml
- name: tdx-kernel
measurement_script: tdx-kernel.sh
reference_value_uri: "rvps:///github.com/confidential-containers/tdx/kernel"
artifacts:
- name: kernel
oci_sha256: "sha256:..."
```

`name` and `measurement_script` may differ when reusing a script or renaming an RV without renaming the plugin file.

## Plugin environment

Set by `reference_values.py build` before each plugin runs:

| Variable | Meaning |
|----------|---------|
| `GIT_<KEY>_ROOT` | Clone root for `git.<key>` (e.g. `GIT_TD_SHIM_ROOT`) |
| `GIT_REPOS_ROOT` | `.work/git` |
| `RV_EXTRACT_DIR` | Extracted Kata payload tree (same as plugin cwd) |
| `COCO_VERSION` | `versions.yaml` → `version` |
| `REPO_ROOT` | Root of this repository |

Plugins must be executable (`chmod +x measurements/*.sh`).

## Extract layout

| Artifacts per RV | Extract target | Plugin cwd |
|------------------|----------------|------------|
| **One** | `.work/extracts/<rv>/<artifact>/` | That directory |
| **Two or more** | All into `.work/extracts/<rv>/` (shared root) | Shared root |

Kata archives unpack with paths such as `opt/kata/share/...` at the archive root. Plugin paths like `./opt/kata/...` are resolved relative to cwd.

For multi-artifact entries, archives are extracted in list order; colliding paths are overwritten (last wins).

## Updating OCI digests

When Kata is bumped, every artifact digest under `reference_values` usually changes. Manually finding and updating each `oci_sha256` across arch files is error-prone and time-consuming, especially when multiple artifacts are listed per entry.

The `update-digests` subcommand exists to automate that repetitive work: given one Kata release tag, it resolves the latest digest for each configured artifact and updates all related YAML files in one pass.

After a Kata release bump:

```bash
python3 reference_values.py update-digests versions.yaml <kata-tag>
```

This updates `oci_sha256` in each file listed in `reference_values_files` (not a full merge into `versions.yaml`). Re-run `verify` and `build` afterward.

> [NOTE!]
> Files are rewritten with PyYAML, so quoting/indentation may change; review the diff before committing. It does not update `kata.revision` or other attestation fields—only the digests.

To bump an external tool, update `git.<key>.digest` in `versions.yaml` manually when changing the pinned commit.

## Local workflow

```bash
pip install -r requirements.txt
python3 reference_values.py verify versions.yaml
python3 reference_values.py build versions.yaml results/reference-values.json
```
76 changes: 76 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1 +1,77 @@
# CoCo Official Release Reference Values

This repository is to calculate and publish the official reference values that correspond to **CoCo (Confidential Containers)** community releases.

## Repository Purpose

- Maintain a declarative mapping of official CoCo release targets in `versions.yaml` + per-arch files under `arch/`
- Verify Kata upstream artifact attestations before building release reference values
- Reproducibly calculate reference values from Kata payloads for each official CoCo release
- Publish generated reference values as workflow/release artifacts for RVPS consumers
- Generate SLSA build provenance attestation metadata for the published output JSON

## How It Works

1. Read `versions.yaml` and load referenced files from `reference_values_files` (for example `arch/x86_64-tdx.yaml`).
2. Verify each configured artifact attestation with `reference_values.py verify`.
- Checks each artifact digest against the expected Kata source repository, source revision, workflow digest, workflow trigger, and main branch workflow ref.
- Tooling: `gh attestation verify`.
3. Run `reference_values.py build`, which for each `reference_values` entry:
- Pulls Kata OCI artifacts (`<kata.oci>/<name>@<oci_sha256>`) and extracts `kata-static-<name>.tar.zst`
- Clones pinned external tool repos from `versions.yaml` → `git`
- Runs the shell plugin named by `measurement_script` under `measurements/` and collects stdout as the reference value
- Tooling: `oras`, `tar`, `git`.
4. Write final output JSON to `results/reference-values.json`.

Measurement command lines live in `measurements/` (not in YAML). See [DEVELOPMENT.md](DEVELOPMENT.md) for how to add or change plugins.

## Local Run

Prerequisites: `python3`, `git`, `oras`, `gh`, `jq`, `tar`, and Python deps from `requirements.txt`.

```bash
pip install -r requirements.txt

# Verify upstream kata provenance attestation
python3 reference_values.py verify versions.yaml

# Generate reference value manifest
python3 reference_values.py build versions.yaml results/reference-values.json

# (Optional) Update all OCI artifact digests in *.yamls using given kata-version
python3 reference_values.py update-digests versions.yaml 3.30.0
```

> [!NOTE]
> If local `gh attestation ...` commands fail with `unknown command "attestation" for "gh"`, upgrade GitHub CLI to a version that includes the attestation subcommand.

## GitHub Actions

Workflow: `.github/workflows/reference-values.yml`

- **pull_request**: verify upstream attestations and build JSON (no release upload)
- **release** (`published`): build, upload `reference-values.json`, attach to the GitHub Release, and run `actions/attest`

## Verify Release Attestation (gh CLI)

When `reference-values.json` is published as a GitHub Release asset, you can verify its artifact attestation with `gh attestation verify`.

```bash
TAG="v0.21.0"

gh release download "$TAG" \
--repo confidential-containers/reference-values \
--pattern "reference-values.json"

gh attestation verify reference-values.json \
--repo confidential-containers/reference-values

# Stricter: pin workflow to the release tag
gh attestation verify reference-values.json \
--repo confidential-containers/reference-values \
--signer-workflow "confidential-containers/reference-values/.github/workflows/reference-values.yml@refs/tags/${TAG}"
```

## Development

To add a reference value, update OCI digests, or write a measurement plugin, see [DEVELOPMENT.md](DEVELOPMENT.md).
18 changes: 18 additions & 0 deletions arch/tdx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
reference_values:
- name: "tdx-kernel"
measurement_script: "tdx-kernel.sh"
arch: "x86_64"
reference_value_uri: "rvps:///github.com/confidential-containers/tdx/kernel"
description: "Measurement of guest kernel image is covered by a CCEL eventlog entry"
artifacts:
- name: "kernel"
oci_sha256: "sha256:0754b7494883f55d003309c0fcda9448e83262007ceb4da6b1e7c30a0fb320bb"

- name: "tdx-mrtd"
measurement_script: "tdx-mrtd.sh"
arch: "x86_64"
reference_value_uri: "rvps:///github.com/confidential-containers/tdx/mr_td"
description: "Measurement of TDVF (TDX Virtual Firmware/OVMF) is covered by MR_TD register."
artifacts:
- name: "ovmf-tdx"
oci_sha256: "sha256:0802af108fbaaf535a348160d68dc2acc7ee06025a1d135b4cdac459cb8a6c4e"
5 changes: 5 additions & 0 deletions internal/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright (c) 2026 Alibaba Cloud
#
# SPDX-License-Identifier: Apache-2.0

"""Internal library for reference_values.py (not a published package)."""
Loading