@@ -10,6 +10,7 @@ import (
10
10
"k8s.io/apimachinery/pkg/util/sets"
11
11
"k8s.io/klog/v2"
12
12
psapi "k8s.io/pod-security-admission/api"
13
+ "k8s.io/pod-security-admission/policy"
13
14
)
14
15
15
16
var (
@@ -40,15 +41,12 @@ func (c *PodSecurityReadinessController) classifyViolatingNamespace(
40
41
return nil
41
42
}
42
43
43
- isUserViolation , err := c .isUserViolation ( ctx , ns , enforceLevel )
44
+ allPods , err := c .kubeClient . CoreV1 (). Pods ( ns . Name ). List ( ctx , metav1. ListOptions {} )
44
45
if err != nil {
45
- klog .V (2 ).ErrorS (err , "Error checking user violations" , "namespace" , ns .Name )
46
- // Transient API server error or temporary resource unavailability (most likely).
47
- // Theoretically, psapi parsing errors could occur that retry without hope for recovery.
46
+ klog .V (2 ).ErrorS (err , "Failed to list pods in namespace" , "namespace" , ns .Name )
48
47
return err
49
48
}
50
-
51
- if isUserViolation {
49
+ if hasUserSCCViolatingPod (c .psaEvaluator , enforceLevel , allPods .Items ) {
52
50
conditions .addViolatingUserSCC (ns )
53
51
return nil
54
52
}
@@ -60,52 +58,49 @@ func (c *PodSecurityReadinessController) classifyViolatingNamespace(
60
58
return nil
61
59
}
62
60
63
- func (c * PodSecurityReadinessController ) isUserViolation (
64
- ctx context.Context ,
65
- ns * corev1.Namespace ,
61
+ func hasUserSCCViolatingPod (
62
+ psaEvaluator policy.Evaluator ,
66
63
enforcementLevel psapi.Level ,
67
- ) (bool , error ) {
68
- allPods , err := c .kubeClient .CoreV1 ().Pods (ns .Name ).List (ctx , metav1.ListOptions {})
69
- if err != nil {
70
- klog .V (2 ).ErrorS (err , "Failed to list pods in namespace" , "namespace" , ns .Name )
71
- return false , err
72
- }
73
-
64
+ pods []corev1.Pod ,
65
+ ) bool {
74
66
var userPods []corev1.Pod
75
- for _ , pod := range allPods . Items {
67
+ for _ , pod := range pods {
76
68
if strings .HasPrefix (pod .Annotations [securityv1 .ValidatedSCCAnnotation ], "restricted-v" ) {
77
- // restricted-v2 is allowed for all system:authenticated, also for ServiceAccounts.
78
- // But ServiceAccounts are not part of the group. So restricted-v2 will always
79
- // result in user-based SCC. So we skip them as the user-based SCCs cause harm
80
- // if they need a higher privileged than restricted .
81
- // We watch for any restricted version above the first one. We might introduce
82
- // restricted-v3 for user namespaces.
69
+ // User-based SCCs are only causing violations if they are higher
70
+ // privilege than whatever ServiceAccounts can provide. The
71
+ // restricted-v* is the lowest privilege possible and can't elevate
72
+ // privileges .
73
+ // We watch for any restricted version above the first one (without a v).
74
+ // We might introduce restricted-v3 for user namespaces.
83
75
continue
84
76
}
85
77
86
78
if pod .Annotations [securityv1 .ValidatedSCCSubjectTypeAnnotation ] == "user" {
87
79
userPods = append (userPods , pod )
88
80
}
89
81
}
90
-
91
82
if len (userPods ) == 0 {
92
- return false , nil // No user pods = violation is from service accounts
83
+ return false // No user pods = violation is based upon service accounts
93
84
}
94
85
95
- enforcementVersion := psapi .LatestVersion ()
86
+ enforcement := psapi.LevelVersion {
87
+ Level : enforcementLevel ,
88
+ Version : psapi .LatestVersion (),
89
+ }
96
90
for _ , pod := range userPods {
97
- results := c . psaEvaluator .EvaluatePod (
98
- psapi. LevelVersion { Level : enforcementLevel , Version : enforcementVersion } ,
91
+ results := psaEvaluator .EvaluatePod (
92
+ enforcement ,
99
93
& pod .ObjectMeta ,
100
94
& pod .Spec ,
101
95
)
102
96
97
+ // results contains between 1 and 2 elements
103
98
for _ , result := range results {
104
99
if ! result .Allowed {
105
- return true , nil
100
+ return true
106
101
}
107
102
}
108
103
}
109
104
110
- return false , nil
105
+ return false
111
106
}
0 commit comments