fix: harden provider and promotion evidence

This commit is contained in:
DongHyeonka
2026-08-02 16:28:24 +09:00
parent 42ffb79997
commit 30ceac23c1
29 changed files with 3961 additions and 1076 deletions
+28
View File
@@ -106,6 +106,27 @@ or direct access to the sealed evidence path. Missing sandbox support, stale or
misplaced outputs, command failure/timeout, and post-command candidate drift
all stop publication.
Provider documents are strict schema v2. Their Ed25519 signature covers the
supervisor-supplied evidence type, validity window, run ID/attempt, independent
32-byte invocation nonce, archived source identity, and all four candidate
digests. Each provider job exposes its supervisor-generated nonce as a job
output; promotion treats those outputs as the independent expected values and
never lets a report define its own expected nonce. A report from another
attempt, source, archive, nonce, or key fingerprint is fail-closed even when it
has been correctly re-signed.
The immutable archive contains a strict producer-local assessment. Promotion
revalidates it from captured archive members without reopening checkout policy
or source paths. The finalizer captures the archive, both reports, and both
public keys once, generates both verification v3 records in memory, and writes
exactly five mode-`0400` files beneath a random mode-`0700` directory in
`RUNNER_TEMP`. The exact five are the captured archive, captured vulnerability
report, captured provenance attestation, generated provider-verification v3,
and generated promotion-verification v3. The promotion record binds the exact
provider-record hash, local-assessment hash, both report hashes, run/source/
candidate identities, both nonces, both key IDs/fingerprints, and canonical
trust-policy hash. It never creates or reuses `.release/promoted-staging`.
The final promotion verification/staging step must be immediately adjacent to
the promoted-release upload, and that upload must not use `always()`. This
reduces the post-verification mutation window but does not seal a pathname
@@ -116,6 +137,13 @@ service and transfer actions also remain outside the candidate's cryptographic
identity: every downstream consumer must revalidate the downloaded archive,
manifest member digests and signed provider evidence. Producer-side adjacency
does not provide consumer-side digest revalidation.
The immediately following upload action still reopens pathnames. The
descriptor-relative staging and cleanup code does not claim an atomic
`renameat2` handoff or close a malicious same-UID Gitea upload adapter; the
staging Gitea smoke/native platform adapter remains the required closure for
that boundary. That smoke must exercise exact-five upload and download plus
cleanup on success, validation failure, upload failure, and cancellation. No
native uploader or `renameat2` guarantee exists in this repository today.
Approved vulnerability exceptions require vulnerability/package identity,
owner, a different reviewer, reason and expiry. Expired or self-approved