Skip to content

TG5 — Evidence ingestion CI (UAT + accepted external bundles) #1271

Description

@njhensley

Parent: #1263 · Labels: enhancement, area/ci (auto, .github/**) ·
Size: M · Depends on: TG2 (the publisher), TG1 (the bucket + dedicated
publish SA + per-SA subject condition)

Goal. An AICR-owned CI job that ingests (a) UAT-emitted evidence bundles and
(b) accepted external-contributor ADR-007 bundles (via
recipes/evidence/<recipe>.yaml pointers), runs TG2's publisher, and publishes —
so contributors never touch the bucket and community provenance is verified to
a real signer policy.

Scope.

  • First-party UAT path: extend the nightly UAT workflows (uat-aws.yaml,
    uat-gcp.yaml) — or add a downstream workflow_run-triggered job — to take each
    run's emitted evidence bundle (OCI ref) and invoke tools/testgrid-publish,
    using the dedicated write-only publish WIF identity. The chosen trigger
    (push-event job vs workflow_run) must match the per-SA subject condition TG1
    defines
    , since the two contexts present different OIDC sub/event_name
    claims — coordinate with TG1 up front. source=uat is derived by TG2 from the
    verified SAN matching the UAT-workflow identity regexp, not asserted here.
  • Community path: a job (triggered on merge to recipes/evidence/**, or on a
    cadence) that reads accepted recipes/evidence/<recipe>.yaml pointers, then
    in a step holding no publish credentials: enforces a trusted-registry
    allow-list
    (e.g. ghcr.io/nvidia/* or a configured set; reject out-of-list
    refs and tag-only refs, bound layer/bundle size), pulls the referenced OCI
    bundle, and re-verifies it with aicr evidence verify pinning both
    --expected-issuer (allowed issuer set) and --expected-identity-regexp (an
    in-tree allowlist of accepted community signer identities, reviewed in the
    pointer PR — empty pins are a no-op, uat-aws.yaml:258-260). Only after a passing
    signer-policy verify does a separate step holding the publish identity invoke
    tools/testgrid-publish (which derives source=community). The AICR publish
    identity
    does the write; the contributor only ever provided a signed bundle + a
    pointer PR. This closes the registry-allowlist follow-up documented in
    recipe-evidence.yaml:37 / recipe-evidence-check.sh:46.
  • Idempotent and safe to re-run (relies on TG2's run-identity build-id); bounded;
    structured logging; clear failure surfacing (operability owned by TG7 — including
    the produced-but-unpublished gap).
  • The recipes/evidence/<recipe>.yaml pointer is a dual-consumer event: it
    also trips Epic: Recipe health tracking (ADR-009 V1) — enumeration, structural soundness, public matrix #1224's (deferred) evidence-freshness axis. Source-of-truth split: Epic: Recipe health tracking (ADR-009 V1) — enumeration, structural soundness, public matrix #1224
    reads the signed pointer for structural/freshness state; TestGrid independently
    ingests the OCI bundle for the live board; the pointer-landed-but-no-column-yet
    lag is expected/transient, not a warning (see TG7 and the Interaction section).

Out of scope. Producing the bundles (UAT runner = the dynamic-clusters epic / existing nightly;
contributor side = ADR-007, shipped). The taxonomy spec (TG6). Deriving source
(TG2). The verification establishes who signed + what they assert, not that the
workload ran — community correctness rests on the maintainer pointer review plus the
prominently-surfaced signer + source=community badge.

Key files. New .github/workflows/testgrid-publish.yaml (or a job appended to
uat-aws.yaml/uat-gcp.yaml); the ingest invokes tools/testgrid-publish (TG2);
verify pinning pkg/cli/evidence_verify.go:78-84; registry-allowlist precedent
.github/workflows/recipe-evidence.yaml:37, .github/scripts/recipe-evidence-check.sh:46;
pointer schema pkg/evidence/attestation/pointer.go and
recipes/evidence/<recipe>.yaml (the directory is created when the first pointer
lands — it does not exist at HEAD, consistent with ADR-007 being design-only). WIF
auth reference uat-gcp.yaml:50-53.

Tests. Workflow-syntax lint; a dry-run/act-style or fixture test that the
ingest job constructs the right tools/testgrid-publish invocation for both UAT and
community paths; an assertion that the workflow uses the dedicated write-only
publish identity (not objectAdmin/objectViewer, not the shared
github-actions@eidosx SA) and that no bucket credentials are exposed to a
fork/PR context (fork-safety, per hippo:reviewer-cicd norms). Verify the community
job (1) enforces the registry allow-list and rejects out-of-list/tag-only refs, (2)
re-runs aicr evidence verify with non-empty issuer + identity pins, and (3)
performs the pull/verify in a credential-free step before the publish step.

Acceptance. Nightly UAT bundles auto-publish to TestGrid; accepted
recipes/evidence/** pointers are ingested and published only after a
registry-allowlist check and a real signer-policy verify; the publish identity is
the dedicated write-only SA whose auth context matches TG1's per-SA subject
condition; contributors never receive bucket-write credentials.


Child of #1263 · staged from docs/design/010-aicr-testgrid.md (TG5).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions