diff --git a/process/drivers/cosign_driver.rs b/process/drivers/cosign_driver.rs index 4907ff83..ad26aa7a 100644 --- a/process/drivers/cosign_driver.rs +++ b/process/drivers/cosign_driver.rs @@ -1,7 +1,9 @@ use std::{fmt::Debug, fs, path::Path}; use blue_build_utils::{ - constants::{COSIGN_PASSWORD, COSIGN_PUB_PATH, COSIGN_YES}, + constants::{ + BB_COSIGN_SIGN_ARGS, BB_COSIGN_VERIFY_ARGS, COSIGN_PASSWORD, COSIGN_PUB_PATH, COSIGN_YES, + }, credentials::Credentials, semver::Version, }; @@ -167,7 +169,7 @@ impl SigningDriver for CosignDriver { ) -> Result<()> { let image = image.clone_with_digest(metadata.digest().into()); let status = { - let c = cmd!( + let mut c = cmd!( env { COSIGN_PASSWORD: "", COSIGN_YES: "true", @@ -182,6 +184,11 @@ impl SigningDriver for CosignDriver { "--recursive", image.to_string(), ); + // Append operator-supplied flags to `cosign sign`, e.g. + // BB_COSIGN_SIGN_ARGS="--tlog-upload=false". Unset => no change. + if let Ok(extra) = std::env::var(BB_COSIGN_SIGN_ARGS) { + c.args(split_extra_args(&extra)); + } trace!("{c:?}"); c } @@ -197,7 +204,7 @@ impl SigningDriver for CosignDriver { fn verify(opts: VerifyOpts) -> Result<()> { let status = { - let c = cmd!( + let mut c = cmd!( "cosign", "verify", match &opts.verify_type { @@ -211,6 +218,11 @@ impl SigningDriver for CosignDriver { }, opts.image.to_string(), ); + // Append operator-supplied flags to `cosign verify`, e.g. + // BB_COSIGN_VERIFY_ARGS="--insecure-ignore-tlog=true". Unset => none. + if let Ok(extra) = std::env::var(BB_COSIGN_VERIFY_ARGS) { + c.args(split_extra_args(&extra)); + } trace!("{c:?}"); c } @@ -225,6 +237,18 @@ impl SigningDriver for CosignDriver { } } +/// Split an operator-supplied list of extra cosign flags (the value of +/// [`BB_COSIGN_SIGN_ARGS`]/[`BB_COSIGN_VERIFY_ARGS`]) into individual +/// arguments. +/// +/// Tokens are separated by any run of ASCII whitespace, so a blank or +/// whitespace-only value yields no arguments. This intentionally does not +/// support shell quoting; each flag must be a single whitespace-free token +/// (e.g. `--tlog-upload=false`). +fn split_extra_args(raw: &str) -> Vec { + raw.split_whitespace().map(ToString::to_string).collect() +} + #[cfg(test)] mod test { use std::{fs, path::Path}; @@ -239,7 +263,26 @@ mod test { opts::{CheckKeyPairOpts, GenerateKeyPairOpts}, }; - use super::CosignDriver; + use super::{CosignDriver, split_extra_args}; + + #[test] + fn split_extra_args_parses_tokens() { + // Unset/blank values contribute no arguments. + assert!(split_extra_args("").is_empty()); + assert!(split_extra_args(" \t \n").is_empty()); + + // A single flag. + assert_eq!( + split_extra_args("--tlog-upload=false"), + ["--tlog-upload=false"] + ); + + // Multiple flags separated by arbitrary whitespace. + assert_eq!( + split_extra_args(" --insecure-ignore-tlog=true --foo=bar\t--baz "), + ["--insecure-ignore-tlog=true", "--foo=bar", "--baz"] + ); + } #[test] fn generate_key_pair() { diff --git a/utils/src/constants.rs b/utils/src/constants.rs index fbd0affd..0d40d619 100644 --- a/utils/src/constants.rs +++ b/utils/src/constants.rs @@ -39,6 +39,18 @@ pub const BB_BUILD_RECHUNK: &str = "BB_BUILD_RECHUNK"; pub const BB_BUILD_RECHUNK_CLEAR_PLAN: &str = "BB_BUILD_RECHUNK_CLEAR_PLAN"; pub const BB_BUILD_REMOVE_BASE_IMAGE: &str = "BB_BUILD_REMOVE_BASE_IMAGE"; pub const BB_BUILD_SQUASH: &str = "BB_BUILD_SQUASH"; +/// Extra whitespace-separated flags appended to the `cosign sign` command. +/// +/// Unset by default (no change). Useful for offline/private registries that +/// cannot reach the public transparency log, e.g. +/// `BB_COSIGN_SIGN_ARGS="--tlog-upload=false"`. +pub const BB_COSIGN_SIGN_ARGS: &str = "BB_COSIGN_SIGN_ARGS"; +/// Extra whitespace-separated flags appended to the `cosign verify` command. +/// +/// Unset by default (no change). Counterpart to [`BB_COSIGN_SIGN_ARGS`] for +/// verifying images signed without a transparency-log entry, e.g. +/// `BB_COSIGN_VERIFY_ARGS="--insecure-ignore-tlog=true"`. +pub const BB_COSIGN_VERIFY_ARGS: &str = "BB_COSIGN_VERIFY_ARGS"; pub const BB_GENISO_ENROLLMENT_PASSWORD: &str = "BB_GENISO_ENROLLMENT_PASSWORD"; pub const BB_GENISO_ISO_NAME: &str = "BB_GENISO_ISO_NAME"; pub const BB_GENISO_SECURE_BOOT_URL: &str = "BB_GENISO_SECURE_BOOT_URL";