@@ -552,29 +552,37 @@ var fullAuthority = []rbacv1.PolicyRule{
552552//
553553// parseEscalationErrorForMissingRules attempts to extract specific RBAC permissions
554554// that were denied due to escalation prevention from a given error's text.
555- // It returns the list of extracted PolicyRules and an error.
555+ // It returns the list of extracted PolicyRules and an error detailing the escalation attempt
556+ // and any resolution errors found.
556557// Note: If parsing is successful, the returned error is derived from the *input* error's
557- // message (specifically the part indicating the escalation attempt), not an error
558- // encountered during the parsing process itself. If parsing fails due to an unexpected
558+ // message, not an error encountered during the parsing process itself. If parsing fails due to an unexpected
559559// error format, a distinct parsing error is returned.
560560func parseEscalationErrorForMissingRules (ecError error ) ([]rbacv1.PolicyRule , error ) {
561- // errRegex captures the standard prefix of an escalation error message
562- errRegex := regexp .MustCompile (`(?s)^(user ".*" \(groups=.*\) is attempting to grant RBAC permissions not currently held):.*?$` )
561+ // errRegex captures the missing permissions and optionally resolution errors from an escalation error message
562+ // Group 1: The list of missing permissions
563+ // Group 2: Optional resolution errors
564+ errRegex := regexp .MustCompile (`(?s)^user ".*" \(groups=.*\) is attempting to grant RBAC permissions not currently held: (.*)(?:; resolution errors: (.*))?$` )
563565 // permRegex extracts the details (APIGroups, Resources, Verbs) of individual permissions listed within the error message
564566 permRegex := regexp .MustCompile (`{APIGroups:\[("[^"]*")], Resources:\[("[^"]*")], Verbs:\[("[^"]*")]}` )
565567
566- errMatches := errRegex .FindAllStringSubmatch (ecError .Error (), - 1 )
567- // Check if the main error message prefix was matched and captured
568- if len (errMatches ) == 0 || len (errMatches [0 ]) < 2 {
568+ errString := ecError .Error ()
569+ errMatches := errRegex .FindStringSubmatch (errString ) // Use FindStringSubmatch for single match expected
570+
571+ // Check if the main error message pattern was matched and captured the required groups
572+ // We expect at least 3 elements: full match, missing permissions, resolution errors (can be empty)
573+ if len (errMatches ) < 3 {
569574 // The error format doesn't match the expected pattern for escalation errors
570575 return nil , fmt .Errorf ("failed to parse escalation error: unexpected format: %w" , ecError )
571576 }
572577
573- // Extract permissions using permRegex
578+ missingPermissionsStr := errMatches [1 ]
579+ resolutionErrorsStr := errMatches [2 ]
580+
581+ // Extract permissions using permRegex from the captured permissions string (Group 1)
574582 permissions := []rbacv1.PolicyRule {}
575- permMatches := permRegex .FindAllStringSubmatch (ecError . Error () , - 1 )
583+ permMatches := permRegex .FindAllStringSubmatch (missingPermissionsStr , - 1 )
576584 for _ , match := range permMatches {
577- // Ensure the match has the expected number of capture groups
585+ // Ensure the match has the expected number of capture groups (full match + 3 groups)
578586 if len (match ) < 4 {
579587 continue // Skip malformed permission strings
580588 }
@@ -585,8 +593,14 @@ func parseEscalationErrorForMissingRules(ecError error) ([]rbacv1.PolicyRule, er
585593 })
586594 }
587595
588- // Return the extracted permissions and the captured escalation message prefix as the error context
589- return permissions , errors .New (errMatches [0 ][1 ])
596+ // Construct the error message to return. Include resolution errors if present
597+ errMsg := "escalation check failed"
598+ if resolutionErrorsStr != "" {
599+ errMsg = fmt .Sprintf ("%s; resolution errors: %s" , errMsg , resolutionErrorsStr )
600+ }
601+
602+ // Return the extracted permissions and the constructed error message
603+ return permissions , errors .New (errMsg )
590604}
591605
592606func hasAggregationRule (clusterRole * rbacv1.ClusterRole ) bool {
0 commit comments