From c2a55552b220e616095846b1338eada783bcc9a2 Mon Sep 17 00:00:00 2001 From: Dan Mihai Date: Tue, 30 Jul 2024 19:33:02 +0000 Subject: [PATCH] agent: fix the AllowRequestsFailingPolicy functionality 1. Use the new value of AllowRequestsFailingPolicy after setting up a new Policy. Before this change, the only way to enable AllowRequestsFailingPolicy was to change the default Policy file, built into the Guest rootfs image. 2. Ignore errors returned by regorus while evaluating Policy rules, if AllowRequestsFailingPolicy was enabled. For example, trying to evaluate the UpdateInterfaceRequest rules using a policy that didn't define any UpdateInterfaceRequest rules results in a "not found" error from regorus. Allow AllowRequestsFailingPolicy := true to bypass that error. 3. Add simple CI test for AllowRequestsFailingPolicy. These changes are restoring functionality that was broken recently by commmit df23eb09a6b7a229f5c099d8a04b799a97ced141. Signed-off-by: Dan Mihai --- src/agent/src/policy.rs | 35 +++++++++++++++---- .../kubernetes/k8s-policy-hard-coded.bats | 22 ++++++++++++ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/agent/src/policy.rs b/src/agent/src/policy.rs index d709515ffd..2416115853 100644 --- a/src/agent/src/policy.rs +++ b/src/agent/src/policy.rs @@ -100,11 +100,7 @@ impl AgentPolicy { } self.engine.add_policy_from_file(default_policy_file)?; - self.engine.set_input_json("{}")?; - self.allow_failures = match self.allow_request("AllowRequestsFailingPolicy", "{}").await { - Ok((allowed, _prints)) => allowed, - Err(_) => false, - }; + self.update_allow_failures_flag().await?; Ok(()) } @@ -116,8 +112,18 @@ impl AgentPolicy { let query = format!("data.agent_policy.{ep}"); self.engine.set_input_json(ep_input)?; - let mut allow = self.engine.eval_bool_query(query, false)?; + let mut allow = match self.engine.eval_bool_query(query, false) { + Ok(a) => a, + Err(e) => { + if !self.allow_failures { + return Err(e); + } + false + } + }; + if !allow && self.allow_failures { + warn!(sl!(), "policy: ignoring error for {ep}"); allow = true; } @@ -134,6 +140,7 @@ impl AgentPolicy { self.engine = Self::new_engine(); self.engine .add_policy("agent_policy".to_string(), policy.to_string())?; + self.update_allow_failures_flag().await?; Ok(()) } @@ -160,4 +167,20 @@ impl AgentPolicy { } } } + + async fn update_allow_failures_flag(&mut self) -> Result<()> { + self.allow_failures = match self.allow_request("AllowRequestsFailingPolicy", "{}").await { + Ok((allowed, _prints)) => { + if allowed { + warn!( + sl!(), + "policy: AllowRequestsFailingPolicy is enabled - will ignore errors" + ); + } + allowed + } + Err(_) => false, + }; + Ok(()) + } } diff --git a/tests/integration/kubernetes/k8s-policy-hard-coded.bats b/tests/integration/kubernetes/k8s-policy-hard-coded.bats index 9246506739..773ec60fe8 100644 --- a/tests/integration/kubernetes/k8s-policy-hard-coded.bats +++ b/tests/integration/kubernetes/k8s-policy-hard-coded.bats @@ -37,6 +37,28 @@ setup() { echo "$exec_output" | grep "ExecProcessRequest is blocked by policy" } +@test "AllowRequestsFailingPolicy := true" { + # Add to the YAML file a policy using just AllowRequestsFailingPolicy := true. Evaluating the rules + # for any Kata Agent request will return false, but AllowRequestsFailingPolicy := true will allow + # those request to be executed. + # + # Warning: this is an insecure policy that shouldn't be used when protecting the confidentiality + # of a pod is important. However, this policy could be useful while debugging a pod. + policy_text=$(printf "package agent_policy\ndefault AllowRequestsFailingPolicy := true") + policy_base64=$(echo "${policy_text}" | base64 -w 0 -) + + yq -i \ + ".metadata.annotations.\"io.katacontainers.config.agent.policy\" = \"${policy_base64}\"" \ + "${pod_yaml}" + + # Create the pod + kubectl create -f "${pod_yaml}" + + # Wait for pod to start + echo "timeout=${timeout}" + kubectl wait --for=condition=Ready --timeout=$timeout pod "$pod_name" +} + teardown() { hard_coded_policy_tests_enabled || skip "Policy tests are disabled."