1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-28 16:20:57 -05:00

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 <bcallaway@google.com>
This commit is contained in:
Bob Callaway 2024-08-31 11:53:46 -04:00 committed by Luca Casonato
parent 0b627bfe32
commit 6034b8dd51
No known key found for this signature in database
GPG key ID: 01A83EB62563811F
2 changed files with 15 additions and 9 deletions

View file

@ -1049,7 +1049,8 @@ async fn publish_package(
sha256: faster_hex::hex_string(&sha2::Sha256::digest(&meta_bytes)), 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]; let tlog_entry = &bundle.verification_material.tlog_entries[0];
log::info!("{}", log::info!("{}",

View file

@ -229,16 +229,16 @@ impl Predicate {
struct ProvenanceAttestation { struct ProvenanceAttestation {
#[serde(rename = "type")] #[serde(rename = "type")]
_type: &'static str, _type: &'static str,
subject: Subject, subject: Vec<Subject>,
predicate_type: &'static str, predicate_type: &'static str,
predicate: Predicate, predicate: Predicate,
} }
impl ProvenanceAttestation { impl ProvenanceAttestation {
pub fn new_github_actions(subject: Subject) -> Self { pub fn new_github_actions(subjects: Vec<Subject>) -> Self {
Self { Self {
_type: INTOTO_STATEMENT_TYPE, _type: INTOTO_STATEMENT_TYPE,
subject, subject: subjects,
predicate_type: SLSA_PREDICATE_TYPE, predicate_type: SLSA_PREDICATE_TYPE,
predicate: Predicate::new_github_actions(), predicate: Predicate::new_github_actions(),
} }
@ -296,7 +296,7 @@ pub struct ProvenanceBundle {
pub async fn generate_provenance( pub async fn generate_provenance(
http_client: &HttpClient, http_client: &HttpClient,
subject: Subject, subjects: Vec<Subject>,
) -> Result<ProvenanceBundle, AnyError> { ) -> Result<ProvenanceBundle, AnyError> {
if !is_gha() { if !is_gha() {
bail!("Automatic provenance is only available in GitHub Actions"); 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 attestation = serde_json::to_string(&slsa)?;
let bundle = attest(http_client, &attestation, INTOTO_PAYLOAD_TYPE).await?; let bundle = attest(http_client, &attestation, INTOTO_PAYLOAD_TYPE).await?;
@ -738,8 +738,13 @@ mod tests {
sha256: "yourmom".to_string(), sha256: "yourmom".to_string(),
}, },
}; };
let slsa = ProvenanceAttestation::new_github_actions(subject); let slsa = ProvenanceAttestation::new_github_actions(vec![subject]);
assert_eq!(slsa.subject.name, "jsr:@divy/sdl2@0.0.1"); assert_eq!(
assert_eq!(slsa.subject.digest.sha256, "yourmom"); 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");
} }
} }