Skip to content

Commit

Permalink
feat: Support verifying URL prefix subjects
Browse files Browse the repository at this point in the history
Add `verify_keyless_prefix()`, which is called when we receive the new
`CallbackRequestType::SigstoreKeylessPrefixVerify{}`.
  • Loading branch information
viccuad committed Jul 4, 2022
1 parent f062d59 commit 0051067
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ serde = { version = "1.0", features = ["derive"] }
tokio = { version = "^1", features = ["rt", "rt-multi-thread"] }
tracing = "0.1"
tracing-futures = "0.2"
url = { version = "2.2.2", features = ["serde"] }
validator = { version = "0.15", features = ["derive"] }
wasmparser = "0.86.0"
wapc = "1.0.0"
Expand Down
49 changes: 49 additions & 0 deletions src/callback_handler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,28 @@ impl CallbackHandler {
warn!("callback handler: cannot send response back: {:?}", e);
}
},
CallbackRequestType::SigstoreKeylessPrefixVerify {
image,
keyless,
annotations,
} => {
let response = get_sigstore_keyless_prefix_verification_cached(&mut self.sigstore_client, image.clone(), keyless, annotations)
.await
.map(|response| {
if response.was_cached {
debug!(?image, "Got sigstore keyless verification from cache");
} else {
debug!(?image, "Got sigstore keylesss verification by querying remote registry");
}
CallbackResponse {
payload: serde_json::to_vec(&response.value).unwrap()
}});

if let Err(e) = req.response_channel.send(response) {
warn!("callback handler: cannot send response back: {:?}", e);
}
},

CallbackRequestType::SigstoreGithubActionsVerify {
image,
owner,
Expand Down Expand Up @@ -333,6 +355,33 @@ async fn get_sigstore_keyless_verification_cached(
.map(cached::Return::new)
}

// Sigstore verifications are time expensive, this can cause a massive slow down
// of policy evaluations, especially inside of PolicyServer.
// Because of that we will keep a cache of the digests results.
//
// Details about this cache:
// * the cache is time bound: cached values are purged after 60 seconds
// * only successful results are cached
#[cached(
time = 60,
result = true,
sync_writes = true,
key = "String",
convert = r#"{ format!("{}{:?}{:?}", image, keyless, annotations)}"#,
with_cached_flag = true
)]
async fn get_sigstore_keyless_prefix_verification_cached(
client: &mut sigstore_verification::Client,
image: String,
keyless: Vec<KeylessInfo>,
annotations: Option<HashMap<String, String>>,
) -> Result<cached::Return<VerificationResponse>> {
client
.verify_keyless_prefix(image, keyless, annotations)
.await
.map(cached::Return::new)
}

// Sigstore verifications are time expensive, this can cause a massive slow down
// of policy evaluations, especially inside of PolicyServer.
// Because of that we will keep a cache of the digests results.
Expand Down
39 changes: 39 additions & 0 deletions src/callback_handler/sigstore_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,45 @@ impl Client {
}
}

pub async fn verify_keyless_prefix(
&mut self,
image: String,
keyless: Vec<KeylessInfo>,
annotations: Option<HashMap<String, String>>,
) -> Result<VerificationResponse> {
if keyless.is_empty() {
return Err(anyhow!("Must provide keyless info"));
}
// Build interim VerificationConfig:
//
let mut signatures_all_of: Vec<Signature> = Vec::new();
for k in keyless.iter() {
let prefix = url::Url::parse(&k.subject).expect("Cannot build url prefix");
let signature = Signature::GenericIssuer {
issuer: k.issuer.clone(),
subject: Subject::UrlPrefix(prefix),
annotations: annotations.clone(),
};
signatures_all_of.push(signature);
}
let verification_config = LatestVerificationConfig {
all_of: Some(signatures_all_of),
any_of: None,
};

let result = self
.verifier
.verify(&image, self.docker_config.as_ref(), &verification_config)
.await;
match result {
Ok(digest) => Ok(VerificationResponse {
digest,
is_trusted: true,
}),
Err(e) => Err(e),
}
}

pub async fn verify_github_actions(
&mut self,
image: String,
Expand Down

0 comments on commit 0051067

Please sign in to comment.