agent: add support to provide default agent policy via env

agent built with policy feature initializes the policy engine using a
policy document from a default path, which is installed & linked during
UVM rootfs build. This commit adds support to provide a default agent
policy as environment variable.

This targets development/testing scenarios where kata-agent
is wanted to be started as a local process.

Fixes #10301

Signed-off-by: Sumedh Alok Sharma <sumsharma@microsoft.com>
This commit is contained in:
Sumedh Alok Sharma 2024-09-12 18:29:59 +05:30
parent fc5a631791
commit cefba08903
4 changed files with 44 additions and 14 deletions

View File

@ -55,6 +55,10 @@ const VSOCK_ADDR: &str = "vsock://-1";
const SERVER_ADDR_ENV_VAR: &str = "KATA_AGENT_SERVER_ADDR";
const LOG_LEVEL_ENV_VAR: &str = "KATA_AGENT_LOG_LEVEL";
const TRACING_ENV_VAR: &str = "KATA_AGENT_TRACING";
#[cfg(feature = "agent-policy")]
// Policy file environment variable to pass a policy document
// to initialize agent policy engine.
const POLICY_FILE_VAR: &str = "KATA_AGENT_POLICY_FILE";
const ERR_INVALID_LOG_LEVEL: &str = "invalid log level";
const ERR_INVALID_LOG_LEVEL_PARAM: &str = "invalid log level parameter";
@ -125,6 +129,8 @@ pub struct AgentConfig {
pub enable_signature_verification: bool,
#[cfg(feature = "guest-pull")]
pub image_policy_file: String,
#[cfg(feature = "agent-policy")]
pub policy_file: String,
}
#[derive(Debug, Deserialize)]
@ -152,6 +158,8 @@ pub struct AgentConfigBuilder {
pub enable_signature_verification: Option<bool>,
#[cfg(feature = "guest-pull")]
pub image_policy_file: Option<String>,
#[cfg(feature = "agent-policy")]
pub policy_file: Option<String>,
}
macro_rules! config_override {
@ -225,6 +233,8 @@ impl Default for AgentConfig {
enable_signature_verification: false,
#[cfg(feature = "guest-pull")]
image_policy_file: String::from(""),
#[cfg(feature = "agent-policy")]
policy_file: String::from(""),
}
}
}
@ -275,6 +285,8 @@ impl FromStr for AgentConfig {
}
config_override!(agent_config_builder, agent_config, secure_storage_integrity);
#[cfg(feature = "agent-policy")]
config_override!(agent_config_builder, agent_config, policy_file);
Ok(agent_config)
}
}
@ -456,6 +468,11 @@ impl AgentConfig {
self.tracing = get_bool_value(&name_value).unwrap_or(false);
}
#[cfg(feature = "agent-policy")]
if let Ok(policy_file) = env::var(POLICY_FILE_VAR) {
self.policy_file = policy_file;
}
}
}
@ -662,6 +679,8 @@ mod tests {
enable_signature_verification: bool,
#[cfg(feature = "guest-pull")]
image_policy_file: &'a str,
#[cfg(feature = "agent-policy")]
policy_file: &'a str,
}
impl Default for TestData<'_> {
@ -688,6 +707,8 @@ mod tests {
enable_signature_verification: false,
#[cfg(feature = "guest-pull")]
image_policy_file: "",
#[cfg(feature = "agent-policy")]
policy_file: "",
}
}
}
@ -1174,6 +1195,14 @@ mod tests {
image_policy_file: "file:///etc/image-policy.json",
..Default::default()
},
#[cfg(feature = "agent-policy")]
// Test environment
TestData {
contents: "",
env_vars: vec!["KATA_AGENT_POLICY_FILE=/tmp/policy.rego"],
policy_file: "/tmp/policy.rego",
..Default::default()
},
];
let dir = tempdir().expect("failed to create tmpdir");
@ -1248,6 +1277,9 @@ mod tests {
"{}",
msg
);
#[cfg(feature = "agent-policy")]
assert_eq!(d.policy_file, config.policy_file, "{}", msg);
for v in vars_to_unset {
env::remove_var(v);
}

View File

@ -600,11 +600,7 @@ fn init_agent_as_init(logger: &Logger, unified_cgroup_hierarchy: bool) -> Result
#[cfg(feature = "agent-policy")]
async fn initialize_policy() -> Result<()> {
AGENT_POLICY
.lock()
.await
.initialize("/etc/kata-opa/default-policy.rego")
.await
AGENT_POLICY.lock().await.initialize().await
}
// The Rust standard library had suppressed the default SIGPIPE behavior,

View File

@ -11,6 +11,7 @@ use crate::rpc::ttrpc_error;
use crate::{AGENT_CONFIG, AGENT_POLICY};
static POLICY_LOG_FILE: &str = "/tmp/policy.txt";
static POLICY_DEFAULT_FILE: &str = "/etc/kata-opa/default-policy.rego";
/// Convenience macro to obtain the scope logger
macro_rules! sl {
@ -85,7 +86,7 @@ impl AgentPolicy {
}
/// Initialize regorus.
pub async fn initialize(&mut self, default_policy_file: &str) -> Result<()> {
pub async fn initialize(&mut self) -> Result<()> {
if AGENT_CONFIG.log_level.as_usize() >= slog::Level::Debug.as_usize() {
self.log_file = Some(
tokio::fs::OpenOptions::new()
@ -98,6 +99,14 @@ impl AgentPolicy {
debug!(sl!(), "policy: log file: {}", POLICY_LOG_FILE);
}
// Check if policy file has been set via AgentConfig
// If empty, use default file.
let mut default_policy_file = AGENT_CONFIG.policy_file.clone();
if default_policy_file.is_empty() {
default_policy_file = POLICY_DEFAULT_FILE.to_string();
}
info!(sl!(), "default policy: {default_policy_file}");
self.engine.add_policy_from_file(default_policy_file)?;
self.update_allow_failures_flag().await?;
Ok(())

View File

@ -33,7 +33,6 @@ agent_log_level="debug"
keep_logs=false
local_policy_file="/opt/kata/test.rego"
policy_file="/etc/kata-opa/default-policy.rego"
cleanup()
{
@ -43,9 +42,7 @@ cleanup()
stop_agent
sudo unlink $policy_file
sudo rm $local_policy_file
sudo rm -rf $(dirname ${policy_file})
local sandbox_dir="/run/sandbox-ns/"
sudo umount -f "${sandbox_dir}/uts" "${sandbox_dir}/ipc" &>/dev/null || true
@ -166,6 +163,7 @@ start_agent()
RUST_BACKTRACE=full \
KATA_AGENT_LOG_LEVEL=${agent_log_level} \
KATA_AGENT_SERVER_ADDR=${local_agent_server_addr} \
KATA_AGENT_POLICY_FILE=${local_policy_file} \
${agent_binary} \
&> ${log_file} \
&
@ -191,12 +189,7 @@ install_policy_doc()
allow_all_rego_file="${repo_root_dir}/src/kata-opa/allow-all.rego"
[ ! -f $allow_all_rego_file ] && die "Failed to locate allow-all.rego file"
local policy_dir=$(dirname ${policy_file})
[ ! -d $policy_dir ] && sudo mkdir -p $policy_dir || true
sudo cp $allow_all_rego_file $local_policy_file
[ ! -f $policy_file ] && sudo ln -s $local_policy_file $policy_file || die "Failed to setup local policy file, exists: $policy_file"
}
# Same reason as above, we do not have the necessary components to start the coco processes