@@ -84,16 +84,25 @@ impl Cmd {
8484 print. infoln ( format ! ( "Collecting GitHub attestation from {url}" ) ) ;
8585 let resp = http:: client ( ) . get ( url) . send ( ) . await ?;
8686 let resp: gh_attest_resp:: Root = resp. json ( ) . await ?;
87- let Some ( attestation) = resp. attestations . first ( ) else {
88- return Err ( Error :: AttestationNotFound ) ;
89- } ;
90- let Ok ( payload) = base64:: engine:: general_purpose:: STANDARD
91- . decode ( & attestation. bundle . dsse_envelope . payload )
92- else {
93- return Err ( Error :: AttestationInvalid ) ;
94- } ;
95- let payload: gh_payload:: Root = serde_json:: from_slice ( & payload) ?;
87+
88+ // Find the SLSA provenance attestation (not the Release attestation)
89+ // GitHub may attach multiple attestations, and we need the one with predicate_type
90+ // matching "https://slsa.dev/provenance/v1"
91+ let payload = resp
92+ . attestations
93+ . iter ( )
94+ . find_map ( |attestation| {
95+ let payload = base64:: engine:: general_purpose:: STANDARD
96+ . decode ( & attestation. bundle . dsse_envelope . payload )
97+ . ok ( ) ?;
98+ let payload: gh_payload:: Root = serde_json:: from_slice ( & payload) . ok ( ) ?;
99+
100+ ( payload. predicate_type == "https://slsa.dev/provenance/v1" ) . then_some ( payload)
101+ } )
102+ . ok_or ( Error :: AttestationNotFound ) ?;
103+
96104 print. checkln ( "Attestation found linked to GitHub Actions Workflow Run:" ) ;
105+
97106 let workflow_repo = payload
98107 . predicate
99108 . build_definition
@@ -117,7 +126,7 @@ impl Cmd {
117126 . build_definition
118127 . resolved_dependencies
119128 . first ( )
120- . unwrap ( )
129+ . ok_or ( Error :: AttestationInvalid ) ?
121130 . digest
122131 . git_commit ;
123132 let runner_environment = payload
0 commit comments