Skip to content

Commit 1573c30

Browse files
committed
add more test cases
1 parent 379477e commit 1573c30

File tree

7 files changed

+513
-10
lines changed

7 files changed

+513
-10
lines changed

src/bundle/dsse.rs

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,17 @@ impl DsseEnvelope {
145145
pub fn signatures(&self) -> &[DsseSignature] {
146146
&self.0.signatures
147147
}
148+
149+
/// Decodes and parses the payload as an in-toto Statement.
150+
///
151+
/// This is a convenience method for DSSE envelopes containing in-toto attestations.
152+
///
153+
/// # Errors
154+
///
155+
/// Returns an error if the payload is not valid UTF-8 or cannot be parsed as a Statement.
156+
pub fn decode_statement(&self) -> Result<Statement, serde_json::Error> {
157+
serde_json::from_slice(&self.0.payload)
158+
}
148159
}
149160

150161
#[cfg(test)]
@@ -278,4 +289,57 @@ mod tests {
278289
let inner = envelope.into_inner();
279290
assert_eq!(inner.payload_type, "test");
280291
}
292+
293+
#[test]
294+
fn test_decode_statement() {
295+
let original_statement = StatementBuilder::new()
296+
.subject(Subject::new("myapp.tar.gz", "sha256", "deadbeef"))
297+
.predicate_type("https://slsa.dev/provenance/v1")
298+
.predicate(json!({
299+
"buildType": "https://example.com/build",
300+
"builder": {"id": "https://example.com/builder"}
301+
}))
302+
.build()
303+
.unwrap();
304+
305+
let envelope = DsseEnvelope::from_statement(&original_statement).unwrap();
306+
307+
// Decode the statement back
308+
let decoded_statement = envelope.decode_statement().unwrap();
309+
310+
// Verify it matches the original
311+
assert_eq!(
312+
decoded_statement.statement_type,
313+
original_statement.statement_type
314+
);
315+
assert_eq!(
316+
decoded_statement.predicate_type,
317+
original_statement.predicate_type
318+
);
319+
assert_eq!(decoded_statement.subject.len(), 1);
320+
assert_eq!(decoded_statement.subject[0].name, "myapp.tar.gz");
321+
assert_eq!(
322+
decoded_statement.subject[0].digest.get("sha256"),
323+
Some(&"deadbeef".to_string())
324+
);
325+
}
326+
327+
#[test]
328+
fn test_decode_statement_v0_1() {
329+
// Test that we can decode v0.1 statements
330+
let v0_1_statement = StatementBuilder::new()
331+
.subject(Subject::new("test.tar.gz", "sha256", "abc123"))
332+
.predicate_type("https://slsa.dev/provenance/v0.2")
333+
.predicate(json!({"buildType": "test"}))
334+
.build_v0_1()
335+
.unwrap();
336+
337+
let envelope = DsseEnvelope::from_statement(&v0_1_statement).unwrap();
338+
let decoded = envelope.decode_statement().unwrap();
339+
340+
assert_eq!(
341+
decoded.statement_type,
342+
crate::bundle::intoto::STATEMENT_TYPE_V0_1
343+
);
344+
}
281345
}

src/bundle/intoto.rs

Lines changed: 74 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,27 +14,32 @@
1414

1515
//! In-toto attestation statement support for creating DSSE bundles.
1616
//!
17-
//! This module provides a builder API for creating in-toto Statement v0.1 attestations
17+
//! This module provides a builder API for creating in-toto Statement attestations
1818
//! that can be signed and wrapped in DSSE envelopes.
1919
//!
20-
//! Note: This implements the v0.1 specification, which is currently used by cosign and Rekor.
21-
//! See: <https://github.com/in-toto/attestation/blob/main/spec/v0.1.0/statement.md>
20+
//! Supports both v0.1 and v1 statement formats:
21+
//! - v0.1: <https://github.com/in-toto/attestation/blob/main/spec/v0.1.0/statement.md>
22+
//! - v1: <https://github.com/in-toto/attestation/blob/main/spec/v1/statement.md>
2223
2324
use serde::{Deserialize, Serialize};
2425
use std::collections::HashMap;
2526

2627
/// The in-toto Statement v0.1 type identifier.
27-
/// Note: v0.1 is the currently used version by cosign and Rekor, not v1.
28-
pub const STATEMENT_TYPE_V1: &str = "https://in-toto.io/Statement/v0.1";
28+
/// Used by older Sigstore implementations and some legacy bundles.
29+
pub const STATEMENT_TYPE_V0_1: &str = "https://in-toto.io/Statement/v0.1";
2930

30-
/// An in-toto Statement v0.1 attestation.
31+
/// The in-toto Statement v1 type identifier.
32+
/// Used by current Sigstore implementations including GitHub Actions.
33+
pub const STATEMENT_TYPE_V1: &str = "https://in-toto.io/Statement/v1";
34+
35+
/// An in-toto Statement attestation.
3136
///
3237
/// This represents a verifiable claim about one or more software artifacts.
33-
/// Note: This uses the v0.1 specification which is currently used by cosign and Rekor.
38+
/// Supports both v0.1 and v1 statement formats.
3439
/// Field order matches the canonical JSON serialization used by cosign.
3540
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
3641
pub struct Statement {
37-
/// The statement type (always "<https://in-toto.io/Statement/v0.1>")
42+
/// The statement type (either "https://in-toto.io/Statement/v0.1" or "https://in-toto.io/Statement/v1")
3843
#[serde(rename = "_type")]
3944
pub statement_type: String,
4045

@@ -145,10 +150,24 @@ impl StatementBuilder {
145150
self
146151
}
147152

148-
/// Builds the statement.
153+
/// Builds the statement using the v1 format.
149154
///
150155
/// Returns an error if required fields are missing.
151156
pub fn build(self) -> Result<Statement, &'static str> {
157+
self.build_with_version(STATEMENT_TYPE_V1)
158+
}
159+
160+
/// Builds the statement using the v0.1 format (for backward compatibility).
161+
///
162+
/// Returns an error if required fields are missing.
163+
pub fn build_v0_1(self) -> Result<Statement, &'static str> {
164+
self.build_with_version(STATEMENT_TYPE_V0_1)
165+
}
166+
167+
/// Builds the statement with a specific version.
168+
///
169+
/// Returns an error if required fields are missing.
170+
fn build_with_version(self, version: &str) -> Result<Statement, &'static str> {
152171
if self.subjects.is_empty() {
153172
return Err("Statement must have at least one subject");
154173
}
@@ -160,7 +179,7 @@ impl StatementBuilder {
160179
let predicate = self.predicate.ok_or("Statement must have a predicate")?;
161180

162181
Ok(Statement {
163-
statement_type: STATEMENT_TYPE_V1.to_string(),
182+
statement_type: version.to_string(),
164183
predicate_type,
165184
subject: self.subjects,
166185
predicate,
@@ -256,4 +275,49 @@ mod tests {
256275
assert_eq!(parsed.statement_type, STATEMENT_TYPE_V1);
257276
assert_eq!(parsed.subject[0].name, "test.tar.gz");
258277
}
278+
279+
#[test]
280+
fn test_statement_v0_1_compatibility() {
281+
// Test that we can create and parse v0.1 statements
282+
let statement = StatementBuilder::new()
283+
.subject(Subject::new("test.tar.gz", "sha256", "abc123"))
284+
.predicate_type("https://slsa.dev/provenance/v0.2")
285+
.predicate(json!({
286+
"buildType": "test"
287+
}))
288+
.build_v0_1()
289+
.unwrap();
290+
291+
assert_eq!(statement.statement_type, STATEMENT_TYPE_V0_1);
292+
293+
// Test that we can round-trip v0.1 statements
294+
let json = serde_json::to_string(&statement).unwrap();
295+
let parsed: Statement = serde_json::from_str(&json).unwrap();
296+
297+
assert_eq!(parsed.statement_type, STATEMENT_TYPE_V0_1);
298+
assert_eq!(parsed.subject[0].name, "test.tar.gz");
299+
}
300+
301+
#[test]
302+
fn test_statement_accepts_both_versions() {
303+
// Test parsing a v0.1 statement
304+
let v0_1_json = r#"{
305+
"_type": "https://in-toto.io/Statement/v0.1",
306+
"subject": [{"name": "test", "digest": {"sha256": "abc123"}}],
307+
"predicateType": "https://example.com/test",
308+
"predicate": {}
309+
}"#;
310+
let v0_1: Statement = serde_json::from_str(v0_1_json).unwrap();
311+
assert_eq!(v0_1.statement_type, STATEMENT_TYPE_V0_1);
312+
313+
// Test parsing a v1 statement
314+
let v1_json = r#"{
315+
"_type": "https://in-toto.io/Statement/v1",
316+
"subject": [{"name": "test", "digest": {"sha256": "abc123"}}],
317+
"predicateType": "https://example.com/test",
318+
"predicate": {}
319+
}"#;
320+
let v1: Statement = serde_json::from_str(v1_json).unwrap();
321+
assert_eq!(v1.statement_type, STATEMENT_TYPE_V1);
322+
}
259323
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
{
2+
"mediaType": "application/vnd.dev.sigstore.bundle+json;version=0.1",
3+
"verificationMaterial": {
4+
"tlogEntries": [
5+
{
6+
"logIndex": "6800908",
7+
"logId": {
8+
"keyId": "wNI9atQGlz+VWfO6LRygH4QUfY/8W4RFwiT5i5WRgB0="
9+
},
10+
"kindVersion": {
11+
"kind": "intoto",
12+
"version": "0.0.2"
13+
},
14+
"integratedTime": "1668034836",
15+
"inclusionPromise": {
16+
"signedEntryTimestamp": "MEYCIQCEx8HKsx9hobZjrNqHCSEJvjMEhc2wU2mUwkI7ButQHAIhAPevmw7piNjE2N1OWHmp9S5kBvlVIg93qu4i9yRaswur"
17+
},
18+
"canonicalizedBody": "eyJhcGlWZXJzaW9uIjoiMC4wLjIiLCJraW5kIjoiaW50b3RvIiwic3BlYyI6eyJjb250ZW50Ijp7ImVudmVsb3BlIjp7InBheWxvYWRUeXBlIjoiYXBwbGljYXRpb24vdm5kLmluLXRvdG8ranNvbiIsInNpZ25hdHVyZXMiOlt7InB1YmxpY0tleSI6IkxTMHRMUzFDUlVkSlRpQkRSVkpVU1VaSlEwRlVSUzB0TFMwdENrMUpTVU51ZWtORFFXbGhaMEYzU1VKQlowbFZRbTV0V2xKMFpHdFBkR1pQTDB4NVp6UXpOVU5TSzFaSmFTdEJkME5uV1VsTGIxcEplbW93UlVGM1RYY0tUbnBGVmsxQ1RVZEJNVlZGUTJoTlRXTXliRzVqTTFKMlkyMVZkVnBIVmpKTlVqUjNTRUZaUkZaUlVVUkZlRlo2WVZka2VtUkhPWGxhVXpGd1ltNVNiQXBqYlRGc1drZHNhR1JIVlhkSWFHTk9UV3BKZUUxVVFUVk5hazEzVFVSTk1WZG9ZMDVOYWtsNFRWUkJOVTFxVFhoTlJFMHhWMnBCUVUxR2EzZEZkMWxJQ2t0dldrbDZhakJEUVZGWlNVdHZXa2w2YWpCRVFWRmpSRkZuUVVWbFZVVTJUM2d2TkRFMFN6QmtRbmd6WXpOWEszUlJOMDVVVTJ4SlZsWXlORmxUWWtJS2JEWldlWFZKVmk5cE1UVkxRMnhUYWxWdk1uRlJkVXRUVlRSRmVtMUlaaklyUlUxcUwxbElXVWhsUWtGRWEwUjRhalpQUTBGVlZYZG5aMFpDVFVFMFJ3cEJNVlZrUkhkRlFpOTNVVVZCZDBsSVowUkJWRUpuVGxaSVUxVkZSRVJCUzBKblozSkNaMFZHUWxGalJFRjZRV1JDWjA1V1NGRTBSVVpuVVZVdlZrZERDbFZJVmxnMVlsaG9aWFF5TVdsMFltbzFWM1pvV25GQmQwaDNXVVJXVWpCcVFrSm5kMFp2UVZVek9WQndlakZaYTBWYVlqVnhUbXB3UzBaWGFYaHBORmtLV2tRNGQwaDNXVVJXVWpCU1FWRklMMEpDVlhkRk5FVlNXVzVLY0ZsWE5VRmFSMVp2V1ZjeGJHTnBOV3BpTWpCM1RFRlpTMHQzV1VKQ1FVZEVkbnBCUWdwQlVWRmxZVWhTTUdOSVRUWk1lVGx1WVZoU2IyUlhTWFZaTWpsMFRESjRkbG95YkhWTU1qbG9aRmhTYjAxSlIwdENaMjl5UW1kRlJVRmtXalZCWjFGRENrSklkMFZsWjBJMFFVaFpRVE5VTUhkaGMySklSVlJLYWtkU05HTnRWMk16UVhGS1MxaHlhbVZRU3pNdmFEUndlV2RET0hBM2J6UkJRVUZIUlZod0t6RUtXRkZCUVVKQlRVRlNla0pHUVdsRlFXdGtTVFk1TkM4NFFqSnlUMlJwZVZsUWJFVnVZMlpTZDJ0MVltOWtUMW8wYW14dE5HYzFNamcxVEd0RFNVaFNjQXB0UjJnMGNEVlBZeXRXYXl0QlMwaE5aSFF3Vm5SRU1pOHJZMkZJVjNsbE1WWnhSRFJ5UjJORFRVRnZSME5EY1VkVFRUUTVRa0ZOUkVFeVkwRk5SMUZEQ2sxQmVVczRkRkUxYlZCRFEybE1hbWxKYzFaelNWcFFXWFpvZGtSU00wUkdiR2sxUVZGNmFsTkRlbU5GVXk5b05XWkNNMGR3WlVSa1FrOTFPWFIxYTJFS2IzZEpkMDVyYjBWWldraFBkR3RoWTB4bGNrdzFNbVZaVTNCV2FtWlljMEV3WjBKTmNVRnViVXhIZDFoMGVtdFdTM0Z4ZWxWdFlscG9RM1k0YlRnMVlncG1kVWxTQ2kwdExTMHRSVTVFSUVORlVsUkpSa2xEUVZSRkxTMHRMUzBLIiwic2lnIjoiVFVWVlEwbEdZeTlDZVV4b1EydFNNbGwwUVUxaWJVcHdNakF5V20xYU5GaFdSMWhHUzJrM2NpdHhOMnh6VGtSUVFXbEZRUzlLZDFneVVHbHNRMHgyYTNGRk9VNUtUVVpMVG00eVF6SnFPR05JTDNwNVJtaFJOalYzY21reVNGazkifV19LCJoYXNoIjp7ImFsZ29yaXRobSI6InNoYTI1NiIsInZhbHVlIjoiNjZiM2RjZmNhNjU5ZTVkNTA1NjAyYzNjOWFmOGZkMmJmNmE0YWZhY2FjMzNiMTc1ZTFkN2UwZWNhYjEwZjg5MCJ9LCJwYXlsb2FkSGFzaCI6eyJhbGdvcml0aG0iOiJzaGEyNTYiLCJ2YWx1ZSI6IjhhNzVmNmM4ZGM0ZDlmNDA3Mjg1YmI0OWQzZTAxOWE1ZTY2NmY0MzQ5OWMyNzA3ZDkyODlhYTI3YzNjMmE2N2UifX19fQ=="
19+
}
20+
],
21+
"timestampVerificationData": {
22+
"rfc3161Timestamps": []
23+
},
24+
"x509CertificateChain": {
25+
"certificates": [
26+
{
27+
"rawBytes": "MIICnzCCAiagAwIBAgIUBnmZRtdkOtfO/Lyg435CR+VIi+AwCgYIKoZIzj0EAwMwNzEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MR4wHAYDVQQDExVzaWdzdG9yZS1pbnRlcm1lZGlhdGUwHhcNMjIxMTA5MjMwMDM1WhcNMjIxMTA5MjMxMDM1WjAAMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEeUE6Ox/414K0dBx3c3W+tQ7NTSlIVV24YSbBl6VyuIV/i15KClSjUo2qQuKSU4EzmHf2+EMj/YHYHeBADkDxj6OCAUUwggFBMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQU/VGCUHVX5bXhet21itbj5WvhZqAwHwYDVR0jBBgwFoAU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0RAQH/BBUwE4ERYnJpYW5AZGVoYW1lci5jb20wLAYKKwYBBAGDvzABAQQeaHR0cHM6Ly9naXRodWIuY29tL2xvZ2luL29hdXRoMIGKBgorBgEEAdZ5AgQCBHwEegB4AHYA3T0wasbHETJjGR4cmWc3AqJKXrjePK3/h4pygC8p7o4AAAGEXp+1XQAABAMARzBFAiEAkdI694/8B2rOdiyYPlEncfRwkubodOZ4jlm4g5285LkCIHRpmGh4p5Oc+Vk+AKHMdt0VtD2/+caHWye1VqD4rGcCMAoGCCqGSM49BAMDA2cAMGQCMAyK8tQ5mPCCiLjiIsVsIZPYvhvDR3DFli5AQzjSCzcES/h5fB3GpeDdBOu9tukaowIwNkoEYZHOtkacLerL52eYSpVjfXsA0gBMqAnmLGwXtzkVKqqzUmbZhCv8m85bfuIR"
28+
},
29+
{
30+
"rawBytes": "MIICGjCCAaGgAwIBAgIUALnViVfnU0brJasmRkHrn/UnfaQwCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMjA0MTMyMDA2MTVaFw0zMTEwMDUxMzU2NThaMDcxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjEeMBwGA1UEAxMVc2lnc3RvcmUtaW50ZXJtZWRpYXRlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE8RVS/ysH+NOvuDZyPIZtilgUF9NlarYpAd9HP1vBBH1U5CV77LSS7s0ZiH4nE7Hv7ptS6LvvR/STk798LVgMzLlJ4HeIfF3tHSaexLcYpSASr1kS0N/RgBJz/9jWCiXno3sweTAOBgNVHQ8BAf8EBAMCAQYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU39Ppz1YkEZb5qNjpKFWixi4YZD8wHwYDVR0jBBgwFoAUWMAeX5FFpWapesyQoZMi0CrFxfowCgYIKoZIzj0EAwMDZwAwZAIwPCsQK4DYiZYDPIaDi5HFKnfxXx6ASSVmERfsynYBiX2X6SJRnZU84/9DZdnFvvxmAjBOt6QpBlc4J/0DxvkTCqpclvziL6BCCPnjdlIB3Pu3BxsPmygUY7Ii2zbdCdliiow="
31+
},
32+
{
33+
"rawBytes": "MIIB9zCCAXygAwIBAgIUALZNAPFdxHPwjeDloDwyYChAO/4wCgYIKoZIzj0EAwMwKjEVMBMGA1UEChMMc2lnc3RvcmUuZGV2MREwDwYDVQQDEwhzaWdzdG9yZTAeFw0yMTEwMDcxMzU2NTlaFw0zMTEwMDUxMzU2NThaMCoxFTATBgNVBAoTDHNpZ3N0b3JlLmRldjERMA8GA1UEAxMIc2lnc3RvcmUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAT7XeFT4rb3PQGwS4IajtLk3/OlnpgangaBclYpsYBr5i+4ynB07ceb3LP0OIOZdxexX69c5iVuyJRQ+Hz05yi+UF3uBWAlHpiS5sh0+H2GHE7SXrk1EC5m1Tr19L9gg92jYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRYwB5fkUWlZql6zJChkyLQKsXF+jAfBgNVHSMEGDAWgBRYwB5fkUWlZql6zJChkyLQKsXF+jAKBggqhkjOPQQDAwNpADBmAjEAj1nHeXZp+13NWBNa+EDsDP8G1WWg1tCMWP/WHPqpaVo0jhsweNFZgSs0eE7wYI4qAjEA2WB9ot98sIkoF3vZYdd3/VtWB5b9TNMea7Ix/stJ5TfcLLeABLE4BNJOsQ4vnBHJ"
34+
}
35+
]
36+
}
37+
},
38+
"dsseEnvelope": {
39+
"payload": "ewogICJfdHlwZSI6ICJodHRwczovL2luLXRvdG8uaW8vU3RhdGVtZW50L3YwLjEiLAogICJzdWJqZWN0IjogWwogICAgewogICAgICAibmFtZSI6ICJzbHNhLXByb3ZlbmFuY2UtMC4wLjcudGd6IiwKICAgICAgImRpZ2VzdCI6IHsKICAgICAgICAic2hhNTEyIjogImJiZmQzNzJmYzliZWViNzc3ZmUzNWQwNWJiMTBjMGM3MGE5NzMzZDM2NmE3NWZlZDdkZDE4ODY2YzczOTFkZTNlZTdlODhiYTc0ZGQ0N2FiZjNlMTVjODQ1ZTU0N2ZjZjBlNWMzZGE4MDg1NGM3NTE1NTQyMjRkM2E2ZDRlNTVmIgogICAgICB9CiAgICB9CiAgXSwKICAicHJlZGljYXRlVHlwZSI6ICJodHRwczovL3Nsc2EuZGV2L3Byb3ZlbmFuY2UvdjAuMiIsCiAgInByZWRpY2F0ZSI6IHsKICAgICJidWlsZFR5cGUiOiAiaHR0cHM6Ly9naXRodWIuY29tL25wbS9zbHNhLXByb3ZlbmFuY2UvZ2hhQHYwIiwKICAgICJidWlsZGVyIjogewogICAgICAiaWQiOiAiaHR0cHM6Ly9naXRodWIuY29tL25wbS9zbHNhLXByb3ZlbmFuY2VAMC4wLjEiCiAgICB9LAogICAgImludm9jYXRpb24iOiB7CiAgICAgICJjb25maWdTb3VyY2UiOiB7CiAgICAgICAgInVyaSI6ICJnaXQraHR0cHM6Ly9naXRodWIuY29tL2dpdGh1Yi9zbHNhLXByb3ZlbmFuY2VAcmVmcy9oZWFkcy9kZW1vIiwKICAgICAgICAiZGlnZXN0IjogewogICAgICAgICAgInNoYTEiOiAiMjljZmYzZGQ2NWY3ODBjMzYwMWJkNDU3YWNiNmZlNGU1OTMxYzgyNSIKICAgICAgICB9LAogICAgICAgICJlbnRyeVBvaW50IjogImRlbW8iCiAgICAgIH0sCiAgICAgICJwYXJhbWV0ZXJzIjoge30sCiAgICAgICJlbnZpcm9ubWVudCI6IHsKICAgICAgICAiR0lUSFVCX0VWRU5UX05BTUUiOiAicHVzaCIsCiAgICAgICAgIkdJVEhVQl9KT0IiOiAicnVuLXByb3ZlbmFuY2UtZGVtbyIsCiAgICAgICAgIkdJVEhVQl9SRUYiOiAicmVmcy9oZWFkcy9kZW1vIiwKICAgICAgICAiR0lUSFVCX1JFRl9UWVBFIjogImJyYW5jaCIsCiAgICAgICAgIkdJVEhVQl9SRVBPU0lUT1JZIjogImdpdGh1Yi9zbHNhLXByb3ZlbmFuY2UiLAogICAgICAgICJHSVRIVUJfUkVQT1NJVE9SWV9PV05FUiI6ICJnaXRodWIiLAogICAgICAgICJHSVRIVUJfUlVOX0FUVEVNUFQiOiAiNCIsCiAgICAgICAgIkdJVEhVQl9SVU5fSUQiOiAiMzAyNDA5MTU0NiIsCiAgICAgICAgIkdJVEhVQl9SVU5fTlVNQkVSIjogIjE3IiwKICAgICAgICAiR0lUSFVCX1NIQSI6ICIyOWNmZjNkZDY1Zjc4MGMzNjAxYmQ0NTdhY2I2ZmU0ZTU5MzFjODI1IiwKICAgICAgICAiR0lUSFVCX1dPUktGTE9XIjogImRlbW8iLAogICAgICAgICJJTUFHRV9PUyI6ICJ1YnVudHUyMCIsCiAgICAgICAgIklNQUdFX1ZFUlNJT04iOiAiMjAyMjA5MDUuMSIsCiAgICAgICAgIlJVTk5FUl9BUkNIIjogIlg2NCIsCiAgICAgICAgIlJVTk5FUl9OQU1FIjogIkdpdEh1YiBBY3Rpb25zIDUwIiwKICAgICAgICAiUlVOTkVSX09TIjogIkxpbnV4IgogICAgICB9CiAgICB9LAogICAgIm1ldGFkYXRhIjogewogICAgICAiYnVpbGRJbnZvY2F0aW9uSWQiOiAiMzAyNDA5MTU0Ni00IiwKICAgICAgImNvbXBsZXRlbmVzcyI6IHsKICAgICAgICAicGFyYW1ldGVycyI6IGZhbHNlLAogICAgICAgICJlbnZpcm9ubWVudCI6IGZhbHNlLAogICAgICAgICJtYXRlcmlhbHMiOiBmYWxzZQogICAgICB9LAogICAgICAicmVwcm9kdWNpYmxlIjogZmFsc2UKICAgIH0sCiAgICAibWF0ZXJpYWxzIjogWwogICAgICB7CiAgICAgICAgInVyaSI6ICJnaXQraHR0cHM6Ly9naXRodWIuY29tL2dpdGh1Yi9zbHNhLXByb3ZlbmFuY2UiLAogICAgICAgICJkaWdlc3QiOiB7CiAgICAgICAgICAic2hhMSI6ICIyOWNmZjNkZDY1Zjc4MGMzNjAxYmQ0NTdhY2I2ZmU0ZTU5MzFjODI1IgogICAgICAgIH0KICAgICAgfQogICAgXQogIH0KfQo=",
40+
"payloadType": "application/vnd.in-toto+json",
41+
"signatures": [
42+
{
43+
"sig": "MEUCIFc/ByLhCkR2YtAMbmJp202ZmZ4XVGXFKi7r+q7lsNDPAiEA/JwX2PilCLvkqE9NJMFKNn2C2j8cH/zyFhQ65wri2HY=",
44+
"keyid": ""
45+
},
46+
{
47+
"sig": "MEUCIFc/ByLhCkR2YtAMbmJp202ZmZ4XVGXFKi7r+q7lsNDPAiEA/JwX2PilCLvkqE9NJMFKNn2C2j8cH/zyFhAAAAAAAHY=",
48+
"keyid": ""
49+
}
50+
]
51+
}
52+
}

0 commit comments

Comments
 (0)