1use crate::analyzer::kubelint::config::{CheckScope, CheckSpec};
6
7pub fn builtin_checks() -> Vec<CheckSpec> {
9 vec![
10 CheckSpec::new(
12 "privileged-container",
13 "Indicates when deployments have containers running in privileged mode.",
14 "Do not run your container as privileged unless it is required.",
15 "privileged",
16 )
17 .with_scope(CheckScope::new(&["DeploymentLike"])),
18 CheckSpec::new(
19 "privilege-escalation",
20 "Alert on containers of deployments that allow privilege escalation.",
21 "Ensure containers do not allow privilege escalation by setting allowPrivilegeEscalation to false.",
22 "privilege-escalation",
23 )
24 .with_scope(CheckScope::new(&["DeploymentLike"])),
25 CheckSpec::new(
26 "run-as-non-root",
27 "Indicates when containers are not set to runAsNonRoot.",
28 "Set runAsNonRoot to true in your container's securityContext.",
29 "run-as-non-root",
30 )
31 .with_scope(CheckScope::new(&["DeploymentLike"])),
32 CheckSpec::new(
33 "read-only-root-fs",
34 "Indicates when containers are running with a read-write root filesystem.",
35 "Set readOnlyRootFilesystem to true in your container's securityContext.",
36 "read-only-root-fs",
37 )
38 .with_scope(CheckScope::new(&["DeploymentLike"])),
39 CheckSpec::new(
40 "drop-net-raw-capability",
41 "Indicates when containers do not drop NET_RAW capability.",
42 "NET_RAW capability allows a container to craft arbitrary network packets. Drop this capability.",
43 "drop-net-raw-capability",
44 )
45 .with_scope(CheckScope::new(&["DeploymentLike"])),
46 CheckSpec::new(
47 "hostnetwork",
48 "Indicates when deployments use the host's network namespace.",
49 "Ensure deployments do not share the host's network namespace.",
50 "host-network",
51 )
52 .with_scope(CheckScope::new(&["DeploymentLike"])),
53 CheckSpec::new(
54 "hostpid",
55 "Indicates when deployments share the host's process namespace.",
56 "Ensure deployments do not share the host's process namespace.",
57 "host-pid",
58 )
59 .with_scope(CheckScope::new(&["DeploymentLike"])),
60 CheckSpec::new(
61 "hostipc",
62 "Indicates when deployments share the host's IPC namespace.",
63 "Ensure deployments do not share the host's IPC namespace.",
64 "host-ipc",
65 )
66 .with_scope(CheckScope::new(&["DeploymentLike"])),
67 CheckSpec::new(
68 "host-mounts",
69 "Indicates when deployments mount sensitive host directories.",
70 "Do not mount sensitive host paths unless absolutely necessary.",
71 "host-mounts",
72 )
73 .with_scope(CheckScope::new(&["DeploymentLike"])),
74 CheckSpec::new(
75 "writable-host-mount",
76 "Indicates when containers mount host directories as writable.",
77 "Mount host paths as read-only unless write access is required.",
78 "writable-host-mount",
79 )
80 .with_scope(CheckScope::new(&["DeploymentLike"])),
81 CheckSpec::new(
82 "docker-sock",
83 "Indicates when deployments mount the Docker socket.",
84 "Do not mount /var/run/docker.sock as it gives full control over Docker.",
85 "host-mounts",
86 )
87 .with_scope(CheckScope::new(&["DeploymentLike"])),
88 CheckSpec::new(
89 "unsafe-proc-mount",
90 "Indicates when containers have unsafe /proc mount.",
91 "Use the Default procMount type unless Unmasked is absolutely required.",
92 "unsafe-proc-mount",
93 )
94 .with_scope(CheckScope::new(&["DeploymentLike"])),
95 CheckSpec::new(
97 "latest-tag",
98 "Indicates when containers use images with the 'latest' tag.",
99 "Use specific image tags instead of 'latest' for reproducible deployments.",
100 "latest-tag",
101 )
102 .with_scope(CheckScope::new(&["DeploymentLike"])),
103 CheckSpec::new(
104 "no-liveness-probe",
105 "Indicates when containers do not have liveness probes configured.",
106 "Add a liveness probe to detect and recover from container failures.",
107 "liveness-probe",
108 )
109 .with_scope(CheckScope::new(&["DeploymentLike"])),
110 CheckSpec::new(
111 "no-readiness-probe",
112 "Indicates when containers do not have readiness probes configured.",
113 "Add a readiness probe to ensure traffic is only sent to healthy containers.",
114 "readiness-probe",
115 )
116 .with_scope(CheckScope::new(&["DeploymentLike"])),
117 CheckSpec::new(
118 "unset-cpu-requirements",
119 "Indicates when containers do not have CPU requirements set.",
120 "Set CPU requests and limits for better resource management.",
121 "cpu-requirements",
122 )
123 .with_scope(CheckScope::new(&["DeploymentLike"])),
124 CheckSpec::new(
125 "unset-memory-requirements",
126 "Indicates when containers do not have memory requirements set.",
127 "Set memory requests and limits for better resource management.",
128 "memory-requirements",
129 )
130 .with_scope(CheckScope::new(&["DeploymentLike"])),
131 CheckSpec::new(
132 "minimum-replicas",
133 "Indicates when deployments have fewer than the minimum recommended replicas.",
134 "Increase the number of replicas for better availability.",
135 "replicas",
136 )
137 .with_scope(CheckScope::new(&["Deployment", "StatefulSet"])),
138 CheckSpec::new(
139 "no-anti-affinity",
140 "Indicates when deployments do not have pod anti-affinity configured.",
141 "Use pod anti-affinity to spread pods across nodes for better availability.",
142 "anti-affinity",
143 )
144 .with_scope(CheckScope::new(&["Deployment", "StatefulSet"])),
145 CheckSpec::new(
146 "no-rolling-update-strategy",
147 "Indicates when deployments do not use a rolling update strategy.",
148 "Use RollingUpdate strategy for zero-downtime deployments.",
149 "rolling-update-strategy",
150 )
151 .with_scope(CheckScope::new(&["Deployment"])),
152 CheckSpec::new(
153 "default-service-account",
154 "Indicates when deployments use the default service account.",
155 "Create and use a dedicated service account for your workloads.",
156 "service-account",
157 )
158 .with_scope(CheckScope::new(&["DeploymentLike"])),
159 CheckSpec::new(
160 "deprecated-service-account",
161 "Indicates when the deprecated serviceAccount field is used.",
162 "Use serviceAccountName instead of the deprecated serviceAccount field.",
163 "deprecated-service-account-field",
164 )
165 .with_scope(CheckScope::new(&["DeploymentLike"])),
166 CheckSpec::new(
168 "access-to-secrets",
169 "Indicates when RBAC rules grant access to secrets.",
170 "Limit access to secrets to only those that need it.",
171 "access-to-secrets",
172 )
173 .with_scope(CheckScope::new(&["Role", "ClusterRole"])),
174 CheckSpec::new(
175 "access-to-create-pods",
176 "Indicates when RBAC rules grant create access to pods.",
177 "Limit the ability to create pods as it can be used for privilege escalation.",
178 "access-to-create-pods",
179 )
180 .with_scope(CheckScope::new(&["Role", "ClusterRole"])),
181 CheckSpec::new(
182 "cluster-admin-role-binding",
183 "Indicates when a ClusterRoleBinding grants cluster-admin.",
184 "Avoid granting cluster-admin to users or service accounts.",
185 "cluster-admin-role-binding",
186 )
187 .with_scope(CheckScope::new(&["ClusterRoleBinding"])),
188 CheckSpec::new(
189 "wildcard-in-rules",
190 "Indicates when RBAC rules use wildcards.",
191 "Avoid wildcards in RBAC rules; be specific about resources and verbs.",
192 "wildcard-in-rules",
193 )
194 .with_scope(CheckScope::new(&["Role", "ClusterRole"])),
195 CheckSpec::new(
197 "dangling-service",
198 "Indicates when services have selectors that do not match any pods.",
199 "Ensure service selectors match labels on pods.",
200 "dangling-service",
201 )
202 .with_scope(CheckScope::new(&["Service"])),
203 CheckSpec::new(
204 "dangling-ingress",
205 "Indicates when ingresses reference non-existent services.",
206 "Ensure ingress backends reference existing services.",
207 "dangling-ingress",
208 )
209 .with_scope(CheckScope::new(&["Ingress"])),
210 CheckSpec::new(
211 "dangling-horizontalpodautoscaler",
212 "Indicates when HPAs target non-existent deployments.",
213 "Ensure HPA scaleTargetRef references an existing deployment.",
214 "dangling-hpa",
215 )
216 .with_scope(CheckScope::new(&["HorizontalPodAutoscaler"])),
217 CheckSpec::new(
218 "dangling-networkpolicy",
219 "Indicates when network policies have selectors that do not match any pods.",
220 "Ensure network policy pod selectors match labels on pods.",
221 "dangling-network-policy",
222 )
223 .with_scope(CheckScope::new(&["NetworkPolicy"])),
224 CheckSpec::new(
225 "mismatching-selector",
226 "Indicates when deployment selectors do not match pod template labels.",
227 "Ensure deployment selector matches pod template labels.",
228 "mismatching-selector",
229 )
230 .with_scope(CheckScope::new(&["Deployment", "StatefulSet", "DaemonSet"])),
231 CheckSpec::new(
232 "duplicate-env-var",
233 "Indicates when containers have duplicate environment variables.",
234 "Remove duplicate environment variables.",
235 "duplicate-env-var",
236 )
237 .with_scope(CheckScope::new(&["DeploymentLike"])),
238 CheckSpec::new(
239 "invalid-target-ports",
240 "Indicates when services have invalid target ports.",
241 "Ensure service target ports reference valid container ports.",
242 "target-port",
243 )
244 .with_scope(CheckScope::new(&["Service"])),
245 CheckSpec::new(
247 "env-var-secret",
248 "Indicates when secrets are passed as environment variables.",
249 "Mount secrets as volumes instead of environment variables.",
250 "env-var-secret",
251 )
252 .with_scope(CheckScope::new(&["DeploymentLike"])),
253 CheckSpec::new(
254 "read-secret-from-env-var",
255 "Indicates when secrets are read from environment variables.",
256 "Consider mounting secrets as files instead.",
257 "read-secret-from-env-var",
258 )
259 .with_scope(CheckScope::new(&["DeploymentLike"])),
260 CheckSpec::new(
261 "ssh-port",
262 "Indicates when containers expose SSH port (22).",
263 "Avoid exposing SSH ports in containers.",
264 "ssh-port",
265 )
266 .with_scope(CheckScope::new(&["DeploymentLike"])),
267 CheckSpec::new(
268 "privileged-ports",
269 "Indicates when containers use privileged ports (< 1024).",
270 "Use non-privileged ports (>= 1024) when possible.",
271 "privileged-ports",
272 )
273 .with_scope(CheckScope::new(&["DeploymentLike"])),
274 CheckSpec::new(
275 "no-extensions-v1beta",
276 "Indicates when deprecated extensions/v1beta1 API is used.",
277 "Use apps/v1 API instead of extensions/v1beta1.",
278 "disallowed-gvk",
279 )
280 .with_scope(CheckScope::new(&["Any"])),
281 CheckSpec::new(
282 "hpa-minimum-replicas",
283 "Indicates when HPA minReplicas is set too low.",
284 "Set HPA minReplicas to at least 2 for high availability.",
285 "hpa-min-replicas",
286 )
287 .with_scope(CheckScope::new(&["HorizontalPodAutoscaler"])),
288 CheckSpec::new(
289 "liveness-port",
290 "Indicates when liveness probe ports do not match container ports.",
291 "Ensure liveness probe ports match defined container ports.",
292 "liveness-port",
293 )
294 .with_scope(CheckScope::new(&["DeploymentLike"])),
295 CheckSpec::new(
296 "readiness-port",
297 "Indicates when readiness probe ports do not match container ports.",
298 "Ensure readiness probe ports match defined container ports.",
299 "readiness-port",
300 )
301 .with_scope(CheckScope::new(&["DeploymentLike"])),
302 CheckSpec::new(
303 "startup-port",
304 "Indicates when startup probe ports do not match container ports.",
305 "Ensure startup probe ports match defined container ports.",
306 "startup-port",
307 )
308 .with_scope(CheckScope::new(&["DeploymentLike"])),
309 CheckSpec::new(
310 "non-existent-service-account",
311 "Indicates when pods reference non-existent service accounts.",
312 "Create the service account or use an existing one.",
313 "non-existent-service-account",
314 )
315 .with_scope(CheckScope::new(&["DeploymentLike"])),
316 CheckSpec::new(
317 "non-isolated-pod",
318 "Indicates when pods are not covered by any network policy.",
319 "Create network policies to isolate pod traffic.",
320 "non-isolated-pod",
321 )
322 .with_scope(CheckScope::new(&["DeploymentLike"])),
323 CheckSpec::new(
324 "pdb-max-unavailable",
325 "Indicates when PDB maxUnavailable is too permissive.",
326 "Set appropriate maxUnavailable for PodDisruptionBudgets.",
327 "pdb-max-unavailable",
328 )
329 .with_scope(CheckScope::new(&["PodDisruptionBudget"])),
330 CheckSpec::new(
331 "pdb-min-available",
332 "Indicates when PDB minAvailable is too permissive.",
333 "Set appropriate minAvailable for PodDisruptionBudgets.",
334 "pdb-min-available",
335 )
336 .with_scope(CheckScope::new(&["PodDisruptionBudget"])),
337 CheckSpec::new(
338 "required-annotation-email",
339 "Indicates when objects are missing required email annotation.",
340 "Add the required annotation to your resource.",
341 "required-annotation",
342 )
343 .with_scope(CheckScope::new(&["Any"])),
344 CheckSpec::new(
345 "required-label-owner",
346 "Indicates when objects are missing required owner label.",
347 "Add the required label to your resource.",
348 "required-label",
349 )
350 .with_scope(CheckScope::new(&["Any"])),
351 CheckSpec::new(
352 "no-node-affinity",
353 "Indicates when deployments do not have node affinity configured.",
354 "Consider using node affinity to control pod placement.",
355 "node-affinity",
356 )
357 .with_scope(CheckScope::new(&["DeploymentLike"])),
358 CheckSpec::new(
359 "restart-policy",
360 "Indicates when pods have inappropriate restart policies.",
361 "Use an appropriate restart policy for your workload type.",
362 "restart-policy",
363 )
364 .with_scope(CheckScope::new(&["Pod"])),
365 CheckSpec::new(
366 "scc-deny-privileged-container",
367 "Indicates when SecurityContextConstraints allow privileged containers.",
368 "Set allowPrivilegedContainer to false in SCC.",
369 "scc-deny-privileged",
370 )
371 .with_scope(CheckScope::new(&["SecurityContextConstraints"])),
372 CheckSpec::new(
373 "sysctls",
374 "Indicates when pods use unsafe sysctls.",
375 "Avoid using unsafe sysctls in pod specifications.",
376 "sysctls",
377 )
378 .with_scope(CheckScope::new(&["DeploymentLike"])),
379 CheckSpec::new(
380 "use-namespace",
381 "Indicates when objects are in the default namespace.",
382 "Deploy resources to a specific namespace, not default.",
383 "use-namespace",
384 )
385 .with_scope(CheckScope::new(&["Any"])),
386 CheckSpec::new(
387 "dangling-networkpolicypeer-podselector",
388 "Indicates when NetworkPolicy peer pod selectors don't match any pods.",
389 "Ensure NetworkPolicy peer selectors match existing pods.",
390 "dangling-network-policy-peer",
391 )
392 .with_scope(CheckScope::new(&["NetworkPolicy"])),
393 CheckSpec::new(
394 "dangling-servicemonitor",
395 "Indicates when ServiceMonitors have selectors that don't match any services.",
396 "Ensure ServiceMonitor selectors match existing services.",
397 "dangling-service-monitor",
398 )
399 .with_scope(CheckScope::new(&["ServiceMonitor"])),
400 CheckSpec::new(
401 "dnsconfig-options",
402 "Indicates when pods have missing recommended DNS config options.",
403 "Add recommended DNS config options for better reliability.",
404 "dnsconfig-options",
405 )
406 .with_scope(CheckScope::new(&["DeploymentLike"])),
407 CheckSpec::new(
408 "env-var-value-from",
409 "Indicates when env vars reference non-existent secrets or configmaps.",
410 "Ensure env var references point to existing resources.",
411 "env-var-value-from",
412 )
413 .with_scope(CheckScope::new(&["DeploymentLike"])),
414 CheckSpec::new(
415 "job-ttl-seconds-after-finished",
416 "Indicates when jobs don't have ttlSecondsAfterFinished set.",
417 "Set ttlSecondsAfterFinished to automatically clean up completed jobs.",
418 "job-ttl-seconds-after-finished",
419 )
420 .with_scope(CheckScope::new(&["Job"])),
421 CheckSpec::new(
422 "priority-class-name",
423 "Indicates when pods don't have a priorityClassName set.",
424 "Set a priorityClassName for important workloads.",
425 "priority-class-name",
426 )
427 .with_scope(CheckScope::new(&["DeploymentLike"])),
428 CheckSpec::new(
429 "service-type",
430 "Indicates when services use the LoadBalancer type.",
431 "Consider using ClusterIP or NodePort instead of LoadBalancer.",
432 "service-type",
433 )
434 .with_scope(CheckScope::new(&["Service"])),
435 CheckSpec::new(
436 "pdb-unhealthy-pod-eviction-policy",
437 "Indicates when PDB unhealthyPodEvictionPolicy is not configured.",
438 "Set unhealthyPodEvictionPolicy to control eviction behavior.",
439 "pdb-unhealthy-pod-eviction-policy",
440 )
441 .with_scope(CheckScope::new(&["PodDisruptionBudget"])),
442 ]
445}
446
447#[cfg(test)]
448mod tests {
449 use super::*;
450
451 #[test]
452 fn test_builtin_checks_count() {
453 let checks = builtin_checks();
454 assert!(
455 checks.len() >= 60,
456 "Expected at least 60 builtin checks, got {}",
457 checks.len()
458 );
459 }
460
461 #[test]
462 fn test_builtin_checks_unique_names() {
463 let checks = builtin_checks();
464 let mut names: Vec<_> = checks.iter().map(|c| &c.name).collect();
465 let original_len = names.len();
466 names.sort();
467 names.dedup();
468 assert_eq!(names.len(), original_len, "Found duplicate check names");
469 }
470}