From 3a63572187ef435e254a4c753d03a39effae0761 Mon Sep 17 00:00:00 2001 From: Bob Callaway Date: Sat, 31 Aug 2024 11:53:46 -0400 Subject: [PATCH] fix(publish): ensure provenance is spec compliant (#25200) Fixes: #25199 Ensures that for the SLSA provenance document generated on publishing, `subject` is an array of ResourceDescriptor objects per the in-toto specification [requirements](https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md#fields). --------- Signed-off-by: Bob Callaway --- cli/tools/registry/mod.rs | 3 ++- cli/tools/registry/provenance.rs | 21 +++++++++++++-------- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/cli/tools/registry/mod.rs b/cli/tools/registry/mod.rs index 24b3051e4f..fbdcd9e779 100644 --- a/cli/tools/registry/mod.rs +++ b/cli/tools/registry/mod.rs @@ -1049,7 +1049,8 @@ async fn publish_package( sha256: faster_hex::hex_string(&sha2::Sha256::digest(&meta_bytes)), }, }; - let bundle = provenance::generate_provenance(http_client, subject).await?; + let bundle = + provenance::generate_provenance(http_client, vec![subject]).await?; let tlog_entry = &bundle.verification_material.tlog_entries[0]; log::info!("{}", diff --git a/cli/tools/registry/provenance.rs b/cli/tools/registry/provenance.rs index ce3d6ff8a8..47169f2132 100644 --- a/cli/tools/registry/provenance.rs +++ b/cli/tools/registry/provenance.rs @@ -229,16 +229,16 @@ impl Predicate { struct ProvenanceAttestation { #[serde(rename = "type")] _type: &'static str, - subject: Subject, + subject: Vec, predicate_type: &'static str, predicate: Predicate, } impl ProvenanceAttestation { - pub fn new_github_actions(subject: Subject) -> Self { + pub fn new_github_actions(subjects: Vec) -> Self { Self { _type: INTOTO_STATEMENT_TYPE, - subject, + subject: subjects, predicate_type: SLSA_PREDICATE_TYPE, predicate: Predicate::new_github_actions(), } @@ -296,7 +296,7 @@ pub struct ProvenanceBundle { pub async fn generate_provenance( http_client: &HttpClient, - subject: Subject, + subjects: Vec, ) -> Result { if !is_gha() { bail!("Automatic provenance is only available in GitHub Actions"); @@ -308,7 +308,7 @@ pub async fn generate_provenance( ); }; - let slsa = ProvenanceAttestation::new_github_actions(subject); + let slsa = ProvenanceAttestation::new_github_actions(subjects); let attestation = serde_json::to_string(&slsa)?; let bundle = attest(http_client, &attestation, INTOTO_PAYLOAD_TYPE).await?; @@ -738,8 +738,13 @@ mod tests { sha256: "yourmom".to_string(), }, }; - let slsa = ProvenanceAttestation::new_github_actions(subject); - assert_eq!(slsa.subject.name, "jsr:@divy/sdl2@0.0.1"); - assert_eq!(slsa.subject.digest.sha256, "yourmom"); + let slsa = ProvenanceAttestation::new_github_actions(vec![subject]); + assert_eq!( + slsa.subject.len(), + 1, + "Subject should be an array per the in-toto specification" + ); + assert_eq!(slsa.subject[0].name, "jsr:@divy/sdl2@0.0.1"); + assert_eq!(slsa.subject[0].digest.sha256, "yourmom"); } }