Files
gstack/.github/workflows/cso-runtime-qualification.yml
Garry TanandOpenAI Codex 4a3c6a8a3c v1.87.0.0 feat: add verified CSO audits and replayable repair bundles (#2852)
* feat(cso): add verified audits and replayable repair bundles

* fix(cso): harden qualification and setup boundaries

* fix(cso): assemble security canaries at runtime

* fix(cso): bound release proof and maintenance work

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): require complete evaluation reports

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): replay expired snapshots from supplied source

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cso): synchronize DNS cancellation assertion

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore(ship): exempt repository owner from liveness proof

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* test(cso): make recheck retention overlap deterministic

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: bump version and changelog (v1.85.0.0)

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): pass native release gates

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: move release to v1.86.0.0

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): resolve rechecks by finding

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* chore: move release to v1.87.0.0

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): pass macOS and Windows release gates

Normalize BSD wc output, compare Windows paths by filesystem identity, preserve portable snapshot race coverage, and narrow POSIX-only Windows fixtures.

Co-Authored-By: OpenAI Codex <noreply@openai.com>

* fix(cso): harden native verification gates

* fix(cso): refine Windows native diagnostics

* test(cso): isolate Windows Git startup failure

* test(cso): stabilize Windows native diagnostics

* fix(cso): support hardened Git on Windows

* fix(cso): close final verification gaps

* test(cso): bound cold Docker fixture setup

* fix(cso): restore cross-platform free-suite gates

---------

Co-authored-by: OpenAI Codex <noreply@openai.com>
2026-09-14 15:14:58 -07:00

110 lines
5.6 KiB
YAML

name: CSO Runtime Qualification
# A private evaluator sends only gate results and public runtime identities.
# Its held-out assertions remain outside this repository. GitHub authenticates
# the dispatch actor; the protected environment supplies the human review gate.
on:
repository_dispatch:
types: [cso-runtime-qualified]
permissions:
contents: read
packages: read
attestations: read
jobs:
qualify:
if: github.ref == 'refs/heads/main' && github.event_name == 'repository_dispatch'
runs-on: ubuntu-24.04
timeout-minutes: 40
environment: cso-runtime-release
permissions:
contents: read
packages: read
attestations: read
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1
with:
persist-credentials: false
- uses: oven-sh/setup-bun@0c5077e51419868618aeaa5fe8019c62421857d6
with:
bun-version: 1.4.0
- name: Require the configured private-evaluator actor and bounded matrix
env:
CSO_QUALIFICATION_ACTOR: ${{ vars.CSO_QUALIFICATION_ACTOR }}
run: |
set -euo pipefail
test -n "$CSO_QUALIFICATION_ACTOR"
test "$GITHUB_ACTOR" = "$CSO_QUALIFICATION_ACTOR"
jq -e '
.action == "cso-runtime-qualified" and
(.client_payload | keys == ["statements"]) and
(.client_payload.statements | type == "array" and length == 10)
' "$GITHUB_EVENT_PATH"
- name: Recheck public visibility and anonymous pulls for every qualified digest
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
mkdir public-image-evidence
jq -c '.client_payload.statements[]' "$GITHUB_EVENT_PATH" | while IFS= read -r statement; do
runtime_id="$(printf '%s' "$statement" | jq -er '.runtimeId | select(test("^[a-z0-9][a-z0-9._-]{0,100}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
platform="$(printf '%s' "$statement" | jq -er '.platform | select(. == "linux/amd64" or . == "linux/arm64")')"
bun run scripts/cso-public-ghcr.ts verify \
--image "$image" --platform "$platform" --repository "$GITHUB_REPOSITORY" \
--output "public-image-evidence/$runtime_id.json" --remove-after
done
- name: Verify each staged image attestation and normalize qualification statements
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail
signer="https://github.com/$GITHUB_REPOSITORY/.github/workflows/cso-runtime-images.yml@refs/heads/main"
workflow="https://github.com/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID"
qualified_at="$(date -u +%Y-%m-%dT%H:%M:%S.000Z)"
mkdir qualification-evidence
jq -c '.client_payload.statements[]' "$GITHUB_EVENT_PATH" | while IFS= read -r statement; do
runtime_id="$(printf '%s' "$statement" | jq -er '.runtimeId | select(test("^[a-z0-9][a-z0-9._-]{0,100}$"))')"
image="$(printf '%s' "$statement" | jq -er '.image | select(test("^ghcr.io/garrytan/gstack/cso-staging/[a-z0-9-]+-(amd64|arm64)@sha256:[a-f0-9]{64}$"))')"
source_commit="$(printf '%s' "$statement" | jq -er '.sourceCommit | select(test("^[a-f0-9]{40}$"))')"
output="qualification-evidence/$runtime_id"
mkdir "$output"
gh attestation verify "oci://$image" --repo "$GITHUB_REPOSITORY" \
--cert-identity "$signer" --source-ref refs/heads/main --source-digest "$source_commit" \
--deny-self-hosted-runners --predicate-type https://slsa.dev/provenance/v1 \
--format json > "$output/provenance-verification.json"
gh attestation verify "oci://$image" --repo "$GITHUB_REPOSITORY" \
--cert-identity "$signer" --source-ref refs/heads/main --source-digest "$source_commit" \
--deny-self-hosted-runners --predicate-type https://spdx.dev/Document/v2.3 \
--format json > "$output/sbom-verification.json"
provenance_digest="sha256:$(sha256sum "$output/provenance-verification.json" | cut -d ' ' -f 1)"
sbom_digest="sha256:$(sha256sum "$output/sbom-verification.json" | cut -d ' ' -f 1)"
printf '%s' "$statement" | jq \
--arg workflow "$workflow" --arg qualifiedAt "$qualified_at" \
--arg provenanceDigest "$provenance_digest" --arg sbomDigest "$sbom_digest" \
'{
schemaVersion:.schemaVersion,helperAbi:.helperAbi,state:.state,
buildRevision:.buildRevision,runtimeId:.runtimeId,stack:.stack,
platform:.platform,image:.image,versions:.versions,sourceCommit:.sourceCommit,
checks:.checks,workflow:$workflow,qualifiedAt:$qualifiedAt,
provenanceDigest:$provenanceDigest,sbomDigest:$sbomDigest
}' \
> "$output/qualified-runtime.json"
done
- name: Enforce the complete release contract before retaining evidence
run: |
set -euo pipefail
bun run scripts/cso-runtime-promotion.ts \
--evidence-root qualification-evidence \
--output runtime-catalog.proof.json
rm runtime-catalog.proof.json
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a
with:
name: cso-qualified-runtime-statements
path: |
qualification-evidence
public-image-evidence
if-no-files-found: error
retention-days: 30