syncable_cli/analyzer/kubelint/templates/
runasnonroot.rs

1//! Run as non-root detection template.
2
3use crate::analyzer::kubelint::context::Object;
4use crate::analyzer::kubelint::extract;
5use crate::analyzer::kubelint::templates::{CheckFunc, ParameterDesc, Template, TemplateError};
6use crate::analyzer::kubelint::types::{Diagnostic, ObjectKindsDesc};
7
8/// Template for detecting containers not running as non-root.
9pub struct RunAsNonRootTemplate;
10
11impl Template for RunAsNonRootTemplate {
12    fn key(&self) -> &str {
13        "run-as-non-root"
14    }
15
16    fn human_name(&self) -> &str {
17        "Run As Non-Root"
18    }
19
20    fn description(&self) -> &str {
21        "Detects containers not configured to run as non-root"
22    }
23
24    fn supported_object_kinds(&self) -> ObjectKindsDesc {
25        ObjectKindsDesc::default()
26    }
27
28    fn parameters(&self) -> Vec<ParameterDesc> {
29        Vec::new()
30    }
31
32    fn instantiate(
33        &self,
34        _params: &serde_yaml::Value,
35    ) -> Result<Box<dyn CheckFunc>, TemplateError> {
36        Ok(Box::new(RunAsNonRootCheck))
37    }
38}
39
40struct RunAsNonRootCheck;
41
42impl CheckFunc for RunAsNonRootCheck {
43    fn check(&self, object: &Object) -> Vec<Diagnostic> {
44        let mut diagnostics = Vec::new();
45
46        if let Some(pod_spec) = extract::pod_spec::extract_pod_spec(&object.k8s_object) {
47            // Check pod-level security context
48            let pod_run_as_non_root = pod_spec
49                .security_context
50                .as_ref()
51                .and_then(|sc| sc.run_as_non_root);
52
53            for container in extract::container::all_containers(pod_spec) {
54                // Container-level overrides pod-level
55                let container_run_as_non_root = container
56                    .security_context
57                    .as_ref()
58                    .and_then(|sc| sc.run_as_non_root);
59
60                let effective_run_as_non_root = container_run_as_non_root.or(pod_run_as_non_root);
61
62                if effective_run_as_non_root != Some(true) {
63                    diagnostics.push(Diagnostic {
64                        message: format!(
65                            "Container '{}' is not configured to run as non-root",
66                            container.name
67                        ),
68                        remediation: Some(
69                            "Set securityContext.runAsNonRoot to true at pod or container level."
70                                .to_string(),
71                        ),
72                    });
73                }
74            }
75        }
76
77        diagnostics
78    }
79}