agent: Set image-rs image security policy

Add two parameters for enabling cosign signature image verification.
- `enable_signature_verification`: to activate signature verification
- `image_policy`: URI of the image policy
config

Signed-off-by: Xynnn007 <xynnn@linux.alibaba.com>
This commit is contained in:
Xynnn007 2024-07-14 19:04:43 +08:00 committed by stevenhorsman
parent 653bc3973f
commit 9606e7ac8b
3 changed files with 110 additions and 15 deletions

View File

@ -131,6 +131,8 @@ The kata agent has the ability to configure agent options in guest kernel comman
| `agent.cdh_api_timeout` | Confidential Data Hub (CDH) API timeout | Allow to configure CDH API timeout(seconds) | integer | `50` |
| `agent.https_proxy` | HTTPS proxy | Allow to configure `https_proxy` in the guest | string | `""` |
| `agent.image_registry_auth` | Image registry credential URI | The URI to where image-rs can find the credentials for pulling images from private registries e.g. `file:///root/.docker/config.json` to read from a file in the guest image, or `kbs:///default/credentials/test` to get the file from the KBS| string | `""` |
| `agent.enable_signature_verification` | Image security policy flag | Whether enable image security policy enforcement. If `true`, the resource indexed by URI `agent.image_policy_file` will be got to work as image pulling policy. | string | `""` |
| `agent.image_policy_file` | Image security policy URI | The URI to where image-rs Typical policy URIs are like `file:///etc/image.json` to read from a file in the guest image, or `kbs:///default/security-policy/test` to get the file from the KBS| string | `""` |
| `agent.log` | Log level | Allow the agent log level to be changed (produces more or less output) | string | `"info"` |
| `agent.log_vport` | Log port | Allow to specify the `vsock` port to read logs | integer | `0` |
| `agent.no_proxy` | NO proxy | Allow to configure `no_proxy` in the guest | string | `""` |

View File

@ -34,6 +34,12 @@ const GUEST_COMPONENTS_PROCS_OPTION: &str = "agent.guest_components_procs";
const IMAGE_REGISTRY_AUTH_OPTION: &str = "agent.image_registry_auth";
const SECURE_STORAGE_INTEGRITY_OPTION: &str = "agent.secure_storage_integrity";
#[cfg(feature = "guest-pull")]
const ENABLE_SIGNATURE_VERIFICATION: &str = "agent.enable_signature_verification";
#[cfg(feature = "guest-pull")]
const IMAGE_POLICY_FILE: &str = "agent.image_policy_file";
// Configure the proxy settings for HTTPS requests in the guest,
// to solve the problem of not being able to access the specified image in some cases.
const HTTPS_PROXY: &str = "agent.https_proxy";
@ -115,6 +121,10 @@ pub struct AgentConfig {
#[cfg(feature = "guest-pull")]
pub image_registry_auth: String,
pub secure_storage_integrity: bool,
#[cfg(feature = "guest-pull")]
pub enable_signature_verification: bool,
#[cfg(feature = "guest-pull")]
pub image_policy_file: String,
}
#[derive(Debug, Deserialize)]
@ -138,6 +148,10 @@ pub struct AgentConfigBuilder {
#[cfg(feature = "guest-pull")]
pub image_registry_auth: Option<String>,
pub secure_storage_integrity: Option<bool>,
#[cfg(feature = "guest-pull")]
pub enable_signature_verification: Option<bool>,
#[cfg(feature = "guest-pull")]
pub image_policy_file: Option<String>,
}
macro_rules! config_override {
@ -207,6 +221,10 @@ impl Default for AgentConfig {
#[cfg(feature = "guest-pull")]
image_registry_auth: String::from(""),
secure_storage_integrity: false,
#[cfg(feature = "guest-pull")]
enable_signature_verification: false,
#[cfg(feature = "guest-pull")]
image_policy_file: String::from(""),
}
}
}
@ -246,8 +264,17 @@ impl FromStr for AgentConfig {
);
config_override!(agent_config_builder, agent_config, guest_components_procs);
#[cfg(feature = "guest-pull")]
config_override!(agent_config_builder, agent_config, image_registry_auth);
{
config_override!(agent_config_builder, agent_config, image_registry_auth);
config_override!(
agent_config_builder,
agent_config,
enable_signature_verification
);
config_override!(agent_config_builder, agent_config, image_policy_file);
}
config_override!(agent_config_builder, agent_config, secure_storage_integrity);
Ok(agent_config)
}
}
@ -372,12 +399,26 @@ impl AgentConfig {
get_guest_components_procs_value
);
#[cfg(feature = "guest-pull")]
parse_cmdline_param!(
param,
IMAGE_REGISTRY_AUTH_OPTION,
config.image_registry_auth,
get_string_value
);
{
parse_cmdline_param!(
param,
IMAGE_REGISTRY_AUTH_OPTION,
config.image_registry_auth,
get_string_value
);
parse_cmdline_param!(
param,
ENABLE_SIGNATURE_VERIFICATION,
config.enable_signature_verification,
get_bool_value
);
parse_cmdline_param!(
param,
IMAGE_POLICY_FILE,
config.image_policy_file,
get_string_value
);
}
parse_cmdline_param!(
param,
SECURE_STORAGE_INTEGRITY_OPTION,
@ -585,6 +626,11 @@ mod tests {
assert!(!config.dev_mode);
assert_eq!(config.log_level, DEFAULT_LOG_LEVEL);
assert_eq!(config.hotplug_timeout, DEFAULT_HOTPLUG_TIMEOUT);
#[cfg(feature = "guest-pull")]
{
assert!(!config.enable_signature_verification);
assert_eq!(config.image_policy_file, "");
}
}
#[test]
@ -612,6 +658,10 @@ mod tests {
#[cfg(feature = "guest-pull")]
image_registry_auth: &'a str,
secure_storage_integrity: bool,
#[cfg(feature = "guest-pull")]
enable_signature_verification: bool,
#[cfg(feature = "guest-pull")]
image_policy_file: &'a str,
}
impl Default for TestData<'_> {
@ -634,6 +684,10 @@ mod tests {
#[cfg(feature = "guest-pull")]
image_registry_auth: "",
secure_storage_integrity: false,
#[cfg(feature = "guest-pull")]
enable_signature_verification: false,
#[cfg(feature = "guest-pull")]
image_policy_file: "",
}
}
}
@ -1102,6 +1156,24 @@ mod tests {
secure_storage_integrity: false,
..Default::default()
},
#[cfg(feature = "guest-pull")]
TestData {
contents: "agent.enable_signature_verification=true",
enable_signature_verification: true,
..Default::default()
},
#[cfg(feature = "guest-pull")]
TestData {
contents: "agent.image_policy_file=kbs:///default/image-policy/test",
image_policy_file: "kbs:///default/image-policy/test",
..Default::default()
},
#[cfg(feature = "guest-pull")]
TestData {
contents: "agent.image_policy_file=file:///etc/image-policy.json",
image_policy_file: "file:///etc/image-policy.json",
..Default::default()
},
];
let dir = tempdir().expect("failed to create tmpdir");
@ -1162,13 +1234,20 @@ mod tests {
msg
);
#[cfg(feature = "guest-pull")]
assert_eq!(d.image_registry_auth, config.image_registry_auth, "{}", msg);
{
assert_eq!(d.image_registry_auth, config.image_registry_auth, "{}", msg);
assert_eq!(
d.enable_signature_verification, config.enable_signature_verification,
"{}",
msg
);
assert_eq!(d.image_policy_file, config.image_policy_file, "{}", msg);
}
assert_eq!(
d.secure_storage_integrity, config.secure_storage_integrity,
"{}",
msg
);
for v in vars_to_unset {
env::remove_var(v);
}

View File

@ -57,13 +57,27 @@ impl ImageService {
pub fn new() -> Self {
let mut image_client = ImageClient::new(PathBuf::from(KATA_IMAGE_WORK_DIR));
#[cfg(feature = "guest-pull")]
if !AGENT_CONFIG.image_registry_auth.is_empty() {
let registry_auth = &AGENT_CONFIG.image_registry_auth;
debug!(sl(), "Set registry auth file {:?}", registry_auth);
image_client.config.file_paths.auth_file = registry_auth.clone();
image_client.config.auth = true;
}
{
if !AGENT_CONFIG.image_registry_auth.is_empty() {
let registry_auth = &AGENT_CONFIG.image_registry_auth;
debug!(sl(), "Set registry auth file {:?}", registry_auth);
image_client.config.file_paths.auth_file = registry_auth.clone();
image_client.config.auth = true;
}
let enable_signature_verification = &AGENT_CONFIG.enable_signature_verification;
debug!(
sl(),
"Enable image signature verification: {:?}", enable_signature_verification
);
image_client.config.security_validate = *enable_signature_verification;
if !AGENT_CONFIG.image_policy_file.is_empty() {
let image_policy_file = &AGENT_CONFIG.image_policy_file;
debug!(sl(), "Use imagepolicy file {:?}", image_policy_file);
image_client.config.file_paths.policy_path = image_policy_file.clone();
}
}
Self { image_client }
}