Repository: FairwindsOps/polaris
Pull request #825 (2022-08-22 13:48:39)

Update changelog.md
This PR bumps to 7.0.2

## Checklist
* [x] I have signed the CLA
* [x] I have updated/added any relevant documentation

## Description
### What's the goal of this PR?

### What changes did you make?

### What alternative solution should we consider, if any?



fairwinds-insights[bot]: ## Fairwinds Insights CI Report
> [View the Full Report](https://insights.fairwinds.com/gh/FairwindsOps/polaris/rb%2Fchangelog)

:white_check_mark: No new Action Items detected!

Patch:
diff --git a/checks/clusterrolePodExecAttach.yaml b/checks/clusterrolePodExecAttach.yaml
new file mode 100644
index 00000000..efc7bdc2
--- /dev/null
+++ b/checks/clusterrolePodExecAttach.yaml
@@ -0,0 +1,55 @@
+successMessage: The ClusterRole does not allow pods/exec or pods/attach
+failureMessage: The ClusterRole allows Pods/exec or pods/attach
+category: Security
+target: rbac.authorization.k8s.io/ClusterRole
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  required: ["metadata", "rules"]
+  anyOf:
+    # Do not alert on default ClusterRoles.
+    - properties:
+        metadata:
+          required: ["name"]
+          properties:
+            name:
+              type: string
+              anyOf:
+                - const: 'admin'
+                - const: "cluster-admin"
+                - const: "edit"
+                - const: "system:aggregate-to-edit"
+                - const: "system:controller:generic-garbage-collector"
+                - const: "system:controller:namespace-controller"
+    - properties:
+        rules:
+          type: array
+          items:
+            type: object
+            not:
+              required: ["apiGroups", "resources", "verbs"]
+              properties:
+                apiGroups:
+                  type: array
+                  contains:
+                    type: string
+                    anyOf:
+                      - const: ""
+                      - const: '*'
+                resources:
+                  type: array
+                  contains:
+                    type: string
+                    anyOf:
+                      - const: '*'
+                      - const: "pods/exec"
+                      - const: "pods/attach"
+                verbs:
+                  type: array
+                  contains:
+                    type: string
+                    anyOf:
+                      - const: '*'
+                      # An exec is also possible by `get`ing a web socket.
+                      - const: 'get'
+                      - const: 'create'
diff --git a/checks/clusterrolebindingClusterAdmin.yaml b/checks/clusterrolebindingClusterAdmin.yaml
new file mode 100644
index 00000000..113b6c30
--- /dev/null
+++ b/checks/clusterrolebindingClusterAdmin.yaml
@@ -0,0 +1,88 @@
+successMessage: The ClusterRoleBinding does not reference the default cluster-admin ClusterRole or one with wildcard permissions
+failureMessage: The ClusterRoleBinding references the default cluster-admin ClusterRole or one with wildcard permissions
+category: Security
+target: rbac.authorization.k8s.io/ClusterRoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Do not alert on default ClusterRoleBindings.
+    - required: ["metadata"]
+      properties:
+        metadata:
+          type: object
+          required: ["name"]
+          properties:
+            name:
+              type: string
+              anyOf:
+                - const: "cluster-admin"
+                - const: "system:controller:generic-garbage-collector"
+                - const: "system:controller:namespace-controller"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "ClusterRole"
+            name:
+              type: string
+              minLength: 1
+              not:
+                const: "cluster-admin"
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/ClusterRole: |
+    type: object
+    # Do not alert on default ClusterRoleBindings.
+    {{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      const: "*"
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      const: '*'
+                  verbs:
+                    type: array
+                    uniqueItems: true
+                    oneOf:
+                      - contains:
+                          type: string
+                          const: '*'
+                      - minItems: 7
+                        items:
+                          type: string
+                          enum:
+                            - "get"
+                            - "list"
+                            - "watch"
+                            - "create"
+                            - "update"
+                            - "patch"
+                            - "delete"
+    {{ end }}
diff --git a/checks/clusterrolebindingPodExecAttach.yaml b/checks/clusterrolebindingPodExecAttach.yaml
new file mode 100644
index 00000000..f1a4a6d4
--- /dev/null
+++ b/checks/clusterrolebindingPodExecAttach.yaml
@@ -0,0 +1,82 @@
+successMessage: The ClusterRoleBinding does not reference a ClusterRole allowing pods/exec or pods/attach
+failureMessage: The ClusterRoleBinding references a ClusterRole that allows Pods/exec, allows pods/attach, or that does not exist
+category: Security
+target: rbac.authorization.k8s.io/ClusterRoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Do not alert on default ClusterRoleBindings.
+    - required: ["metadata"]
+      properties:
+        metadata:
+          type: object
+          required: ["name"]
+          properties:
+            name:
+              type: string
+              anyOf:
+                - const: "cluster-admin"
+                - const: "system:controller:generic-garbage-collector"
+                - const: "system:controller:namespace-controller"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "ClusterRole"
+            name:
+              type: string
+              minLength: 1
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/ClusterRole: |
+    type: object
+    # Do not alert on default ClusterRoleBindings.
+    {{ if and (ne .metadata.name "cluster-admin") (ne .metadata.name "system:controller:generic-garbage-collector") (ne .metadata.name "system:controller:namespace-controller") }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: ""
+                        - const: '*'
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        - const: "pods/exec"
+                        - const: "pods/attach"
+                  verbs:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        # An exec is also possible by `get`ing a web socket.
+                        - const: 'get'
+                        - const: 'create'
+    {{ end }}
diff --git a/checks/rolePodExecAttach.yaml b/checks/rolePodExecAttach.yaml
new file mode 100644
index 00000000..61c27021
--- /dev/null
+++ b/checks/rolePodExecAttach.yaml
@@ -0,0 +1,45 @@
+successMessage: The Role does not allow pods/exec or pods/attach
+failureMessage: The Role allows Pods/exec or pods/attach
+category: Security
+target: rbac.authorization.k8s.io/Role
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  required: ["metadata", "rules"]
+  properties:
+    metadata:
+      required: ["name"]
+      properties:
+        name:
+          type: string
+    rules:
+      type: array
+      items:
+        type: object
+        not:
+          required: ["apiGroups", "resources", "verbs"]
+          properties:
+            apiGroups:
+              type: array
+              contains:
+                type: string
+                anyOf:
+                  - const: ""
+                  - const: '*'
+            resources:
+              type: array
+              contains:
+                type: string
+                anyOf:
+                  - const: '*'
+                  - const: "pods/exec"
+                  - const: "pods/attach"
+            verbs:
+              type: array
+              contains:
+                type: string
+                anyOf:
+                  - const: '*'
+                  # An exec is also possible by `get`ing a web socket.
+                  - const: 'get'
+                  - const: 'create'
diff --git a/checks/rolebindingClusterAdminClusterRole.yaml b/checks/rolebindingClusterAdminClusterRole.yaml
new file mode 100644
index 00000000..89d845b8
--- /dev/null
+++ b/checks/rolebindingClusterAdminClusterRole.yaml
@@ -0,0 +1,84 @@
+successMessage: The RoleBinding does not reference the default cluster-admin ClusterRole or one with wildcard permissions
+failureMessage: The RoleBinding references the default cluster-admin ClusterRole or one with wildcard permissions
+category: Security
+target: rbac.authorization.k8s.io/RoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Pass RoleBindings that point to a Role.
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["kind"]
+          properties:
+            kind:
+              type: string
+              const: "Role"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "ClusterRole"
+            name:
+              type: string
+              minLength: 1
+              not:
+                const: "cluster-admin"
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/ClusterRole: |
+    type: object
+    # This schema is validated for all roleBindings, regardless of their roleRef.
+    {{ if eq .roleRef.kind "ClusterRole" }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      const: "*"
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      const: '*'
+                  verbs:
+                    type: array
+                    uniqueItems: true
+                    oneOf:
+                      - contains:
+                          type: string
+                          const: '*'
+                      - minItems: 7
+                        items:
+                          type: string
+                          enum:
+                            - "get"
+                            - "list"
+                            - "watch"
+                            - "create"
+                            - "update"
+                            - "patch"
+                            - "delete"
+    {{ end }}
diff --git a/checks/rolebindingClusterAdminRole.yaml b/checks/rolebindingClusterAdminRole.yaml
new file mode 100644
index 00000000..914497b4
--- /dev/null
+++ b/checks/rolebindingClusterAdminRole.yaml
@@ -0,0 +1,82 @@
+successMessage: The RoleBinding does not reference a Role with wildcard permissions
+failureMessage: The RoleBinding references a Role with wildcard permissions
+category: Security
+target: rbac.authorization.k8s.io/RoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Pass RoleBindings that point to a ClusterRole.
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["kind"]
+          properties:
+            kind:
+              type: string
+              const: "ClusterRole"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "Role"
+            name:
+              type: string
+              minLength: 1
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/Role: |
+    type: object
+    # This schema is validated for all roleBindings, regardless of their roleRef.
+    {{ if eq .roleRef.kind "Role" }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      const: "*"
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      const: '*'
+                  verbs:
+                    type: array
+                    uniqueItems: true
+                    oneOf:
+                      - contains:
+                          type: string
+                          const: '*'
+                      - minItems: 7
+                        items:
+                          type: string
+                          enum:
+                            - "get"
+                            - "list"
+                            - "watch"
+                            - "create"
+                            - "update"
+                            - "patch"
+                            - "delete"
+    {{ end }}
diff --git a/checks/rolebindingClusterRolePodExecAttach.yaml b/checks/rolebindingClusterRolePodExecAttach.yaml
new file mode 100644
index 00000000..87e1c02e
--- /dev/null
+++ b/checks/rolebindingClusterRolePodExecAttach.yaml
@@ -0,0 +1,78 @@
+successMessage: The RoleBinding does not reference a ClusterRole allowing pods/exec or pods/attach
+failureMessage: The RoleBinding references a ClusterRole that allows Pods/exec, allows pods/attach, or that does not exist
+category: Security
+target: rbac.authorization.k8s.io/RoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Pass RoleBindings that point to a Role.
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["kind"]
+          properties:
+            kind:
+              type: string
+              const: "Role"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "ClusterRole"
+            name:
+              type: string
+              minLength: 1
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/ClusterRole: |
+    type: object
+    # This schema is validated for all roleBindings, regardless of their roleRef.
+    {{ if eq .roleRef.kind "ClusterRole" }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: ""
+                        - const: '*'
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        - const: "pods/exec"
+                        - const: "pods/attach"
+                  verbs:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        # An exec is also possible by `get`ing a web socket.
+                        - const: 'get'
+                        - const: 'create'
+    {{ end }}
diff --git a/checks/rolebindingRolePodExecAttach.yaml b/checks/rolebindingRolePodExecAttach.yaml
new file mode 100644
index 00000000..06fb8287
--- /dev/null
+++ b/checks/rolebindingRolePodExecAttach.yaml
@@ -0,0 +1,81 @@
+successMessage: The RoleBinding does not reference a Role allowing Pod exec or attach
+failureMessage: The RoleBinding references a Role that allows Pods/exec, allows pods/attach, or that does not exist
+category: Security
+target: rbac.authorization.k8s.io/RoleBinding
+schemaString: |
+  '$schema': http://json-schema.org/draft-07/schema
+  type: object
+  anyOf:
+    # Pass RoleBindings that point to a ClusterRole.
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "Role"
+    - required: ["roleRef"]
+      properties:
+        roleRef:
+          required: ["apiGroup", "kind", "name"]
+          properties:
+            apiGroup:
+              type: string
+              const: "rbac.authorization.k8s.io"
+            kind:
+              type: string
+              const: "Role"
+            name:
+              type: string
+              minLength: 1
+additionalSchemaStrings:
+  rbac.authorization.k8s.io/Role: |
+    type: object
+    # This schema is validated for all roleBindings, regardless of their roleRef.
+    {{ if eq .roleRef.kind "Role" }}
+    required: ["metadata", "rules"]
+    allOf:
+      - properties:
+          metadata:
+            required: ["name"]
+            properties:
+              name:
+                type: string
+                const: "{{ .roleRef.name }}"
+      - properties:
+          rules:
+            type: array
+            items:
+              type: object
+              not:
+                required: ["apiGroups", "resources", "verbs"]
+                properties:
+                  apiGroups:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: ""
+                        - const: '*'
+                  resources:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        - const: "pods/exec"
+                        - const: "pods/attach"
+                  verbs:
+                    type: array
+                    contains:
+                      type: string
+                      anyOf:
+                        - const: '*'
+                        # An exec is also possible by `get`ing a web socket.
+                        - const: 'get'
+                        - const: 'create'
+    {{ end }}
diff --git a/docs/changelog.md b/docs/changelog.md
index a8f0339a..8b7c7bdf 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -5,6 +5,11 @@ meta:
     content: "Fairwinds Polaris | Changelog"
 
 ---
+## 7.0.2
+* Fixes for pretty CLI output
+* Some new checks (disabled by default)
+* Some additional features in templating engine
+
 ## 7.0.1
 * Documentation updates
 
diff --git a/examples/config-full.yaml b/examples/config-full.yaml
index 23c6c93e..15804c58 100644
--- a/examples/config-full.yaml
+++ b/examples/config-full.yaml
@@ -27,6 +27,11 @@ checks:
   hostPortSet: warning
   sensitiveContainerEnvVar: danger
   sensitiveConfigmapContent: danger
+  clusterrolePodExecAttach: danger
+  rolePodExecAttach: danger
+  clusterrolebindingPodExecAttach: danger
+  rolebindingClusterRolePodExecAttach: danger
+  rolebindingRolePodExecAttach: danger
   # custom
   resourceLimits: warning
   imageRegistry: danger
diff --git a/go.mod b/go.mod
index 4fbb5b48..5cccdad3 100644
--- a/go.mod
+++ b/go.mod
@@ -16,9 +16,9 @@ require (
 	golang.org/x/text v0.3.7 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1
-	k8s.io/api v0.24.3
-	k8s.io/apimachinery v0.24.3
-	k8s.io/client-go v0.24.3
+	k8s.io/api v0.24.4
+	k8s.io/apimachinery v0.24.4
+	k8s.io/client-go v0.24.4
 	sigs.k8s.io/controller-runtime v0.12.3
 	sigs.k8s.io/yaml v1.3.0
 )
diff --git a/go.sum b/go.sum
index 293dbd74..38569597 100644
--- a/go.sum
+++ b/go.sum
@@ -1147,17 +1147,17 @@ honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg=
-k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY=
-k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI=
+k8s.io/api v0.24.4 h1:I5Y645gJ8zWKawyr78lVfDQkZrAViSbeRXsPZWTxmXk=
+k8s.io/api v0.24.4/go.mod h1:42pVfA0NRxrtJhZQOvRSyZcJihzAdU59WBtTjYcB0/M=
 k8s.io/apiextensions-apiserver v0.24.2 h1:/4NEQHKlEz1MlaK/wHT5KMKC9UKYz6NZz6JE6ov4G6k=
 k8s.io/apiextensions-apiserver v0.24.2/go.mod h1:e5t2GMFVngUEHUd0wuCJzw8YDwZoqZfJiGOW6mm2hLQ=
 k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
-k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg=
-k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
+k8s.io/apimachinery v0.24.4 h1:S0Ur3J/PbivTcL43EdSdPhqCqKla2NIuneNwZcTDeGQ=
+k8s.io/apimachinery v0.24.4/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
 k8s.io/apiserver v0.24.2/go.mod h1:pSuKzr3zV+L+MWqsEo0kHHYwCo77AT5qXbFXP2jbvFI=
 k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30=
-k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY=
-k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw=
+k8s.io/client-go v0.24.4 h1:hIAIJZIPyaw46AkxwyR0FRfM/pRxpUNTd3ysYu9vyRg=
+k8s.io/client-go v0.24.4/go.mod h1:+AxlPWw/H6f+EJhRSjIeALaJT4tbeB/8g9BNvXGPd0Y=
 k8s.io/code-generator v0.24.2/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
 k8s.io/component-base v0.24.2 h1:kwpQdoSfbcH+8MPN4tALtajLDfSfYxBDYlXobNWI6OU=
 k8s.io/component-base v0.24.2/go.mod h1:ucHwW76dajvQ9B7+zecZAP3BVqvrHoOxm8olHEg0nmM=
diff --git a/pkg/config/checks.go b/pkg/config/checks.go
index 85387081..f15a2e8b 100644
--- a/pkg/config/checks.go
+++ b/pkg/config/checks.go
@@ -59,6 +59,14 @@ var (
 		"missingPodDisruptionBudget",
 		"missingNetworkPolicy",
 		"sensitiveConfigmapContent",
+		"clusterrolePodExecAttach",
+		"rolePodExecAttach",
+		"clusterrolebindingPodExecAttach",
+		"rolebindingClusterRolePodExecAttach",
+		"rolebindingRolePodExecAttach",
+		"clusterrolebindingClusterAdmin",
+		"rolebindingClusterAdminClusterRole",
+		"rolebindingClusterAdminRole",
 	}
 )
 


Test patch:
diff --git a/test/checks/clusterrolePodExecAttach/failure.all_wildcards.yaml b/test/checks/clusterrolePodExecAttach/failure.all_wildcards.yaml
new file mode 100644
index 00000000..09a04e59
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.all_wildcards.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole apiGroups, resources, and verbs are all * which allows pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.attach_explicit.yaml b/test/checks/clusterrolePodExecAttach/failure.attach_explicit.yaml
new file mode 100644
index 00000000..61c69eca
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.attach_explicit.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.attach_using_verb_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.attach_using_verb_wildcard.yaml
new file mode 100644
index 00000000..3de50393
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.attach_using_verb_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "*" ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..ba26bae4
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ create ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..fd0ccc82
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..8106791b
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.exec_explicit.yaml b/test/checks/clusterrolePodExecAttach/failure.exec_explicit.yaml
new file mode 100644
index 00000000..2f5dd88f
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.exec_explicit.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/exec.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.exec_verb_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.exec_verb_wildcard.yaml
new file mode 100644
index 00000000..6c041780
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.exec_verb_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/exec using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "*" ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..676b83d3
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ get ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..908bbdf6
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ get ]
diff --git a/test/checks/clusterrolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml b/test/checks/clusterrolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..a5da2b58
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,9 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ get ]
diff --git a/test/checks/clusterrolePodExecAttach/success.allow_unrelated_perms.yaml b/test/checks/clusterrolePodExecAttach/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..229853cc
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/success.allow_unrelated_perms.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the ClusterRole does not allow pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
diff --git a/test/checks/clusterrolePodExecAttach/success.attach_wrong_verb.yaml b/test/checks/clusterrolePodExecAttach/success.attach_wrong_verb.yaml
new file mode 100644
index 00000000..96f414a7
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/success.attach_wrong_verb.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the ClusterRole allows pods/attach but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_admin.yaml b/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_admin.yaml
new file mode 100644
index 00000000..f4b13166
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_admin.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the ClusterRole is an expected default one (by name).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: admin
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "create" ]
diff --git a/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_clusteradmin.yaml b/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_clusteradmin.yaml
new file mode 100644
index 00000000..89e59c5c
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/success.defaultclusterrole_clusteradmin.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the ClusterRole is an expected default one (by name).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: cluster-admin
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "create" ]
diff --git a/test/checks/clusterrolePodExecAttach/success.exec_wrong_verb.yaml b/test/checks/clusterrolePodExecAttach/success.exec_wrong_verb.yaml
new file mode 100644
index 00000000..a2c74a3e
--- /dev/null
+++ b/test/checks/clusterrolePodExecAttach/success.exec_wrong_verb.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the ClusterRole allows pods/exec but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs.yaml b/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs.yaml
new file mode 100644
index 00000000..70577ece
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs.yaml
@@ -0,0 +1,33 @@
+# This fails because the clusterRoleBinding references a ClusterRole that uses all wildcards and all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs_different_order.yaml b/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs_different_order.yaml
new file mode 100644
index 00000000..a7510c9e
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/failure.all_verbs_different_order.yaml
@@ -0,0 +1,33 @@
+# This fails because the clusterRoleBinding references a ClusterRole that uses all wildcards and all verbs (in different order from failure.all_verbs.yaml).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "delete", "update", "create", "patch", "watch" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingClusterAdmin/failure.default_clusteradmin_clusterrole.yaml b/test/checks/clusterrolebindingClusterAdmin/failure.default_clusteradmin_clusterrole.yaml
new file mode 100644
index 00000000..3b22f510
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/failure.default_clusteradmin_clusterrole.yaml
@@ -0,0 +1,26 @@
+# This fails because the ClusterRoleBinding references the default cluster-admin ClusterRole.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole emulates the default cluster-admin one, only by name.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: cluster-admin
+rules:
+- apiGroups:
+  - ''
+  resources:
+  - 'deployments'
+  verbs:
+  - 'get'
diff --git a/test/checks/clusterrolebindingClusterAdmin/failure.wildcards.yaml b/test/checks/clusterrolebindingClusterAdmin/failure.wildcards.yaml
new file mode 100644
index 00000000..d1c7594e
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/failure.wildcards.yaml
@@ -0,0 +1,33 @@
+# This fails because the clusterRoleBinding references a ClusterRole that uses all wildcards.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingClusterAdmin/success.allow_unrelated_perms.yaml b/test/checks/clusterrolebindingClusterAdmin/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..326979d5
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/success.allow_unrelated_perms.yaml
@@ -0,0 +1,22 @@
+# This succeeds because the ClusterRoleBinding references a ClusterRole with safe permissions.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "deployments" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingClusterAdmin/success.explicit_apigroups.yaml b/test/checks/clusterrolebindingClusterAdmin/success.explicit_apigroups.yaml
new file mode 100644
index 00000000..d1e535fe
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/success.explicit_apigroups.yaml
@@ -0,0 +1,33 @@
+# This succeeds because the clusterRoleBinding references a ClusterRole with a safer subset of apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingClusterAdmin/success.explicit_resources.yaml b/test/checks/clusterrolebindingClusterAdmin/success.explicit_resources.yaml
new file mode 100644
index 00000000..a5e9cabe
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/success.explicit_resources.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the clusterRoleBinding references a ClusterRole with a safer subset of resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
+
diff --git a/test/checks/clusterrolebindingClusterAdmin/success.explicit_verbs.yaml b/test/checks/clusterrolebindingClusterAdmin/success.explicit_verbs.yaml
new file mode 100644
index 00000000..2000a702
--- /dev/null
+++ b/test/checks/clusterrolebindingClusterAdmin/success.explicit_verbs.yaml
@@ -0,0 +1,33 @@
+# This succeeds because the clusterRoleBinding references a ClusterRole with a safer subset of verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+  # This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.all_wildcards.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.all_wildcards.yaml
new file mode 100644
index 00000000..26d4a61f
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.all_wildcards.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole apiGroups, resources, and verbs are all * which allows pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.attach_explicit.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.attach_explicit.yaml
new file mode 100644
index 00000000..dd764f82
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.attach_explicit.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.attach_using_verb_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.attach_using_verb_wildcard.yaml
new file mode 100644
index 00000000..518b5a54
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.attach_using_verb_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.binding_points_to_missing_ref.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.binding_points_to_missing_ref.yaml
new file mode 100644
index 00000000..83ba5c0f
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.binding_points_to_missing_ref.yaml
@@ -0,0 +1,13 @@
+# This fails because the roleRef points to a ClusterRole that does not exist.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: does-not-exist
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..744cddbf
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..3a2eb69b
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..17095f6f
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.exec_explicit.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.exec_explicit.yaml
new file mode 100644
index 00000000..83a00847
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.exec_explicit.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/exec.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.exec_verb_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.exec_verb_wildcard.yaml
new file mode 100644
index 00000000..9033e423
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.exec_verb_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/exec using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..19bda2bf
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..5479c40a
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml b/test/checks/clusterrolebindingPodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..a0322012
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,22 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/success.allow_unrelated_perms.yaml b/test/checks/clusterrolebindingPodExecAttach/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..d60d661e
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/success.allow_unrelated_perms.yaml
@@ -0,0 +1,22 @@
+# This succeeds because the ClusterRole does not allow pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/success.attach_wrong_verb.yaml b/test/checks/clusterrolebindingPodExecAttach/success.attach_wrong_verb.yaml
new file mode 100644
index 00000000..23c67957
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/success.attach_wrong_verb.yaml
@@ -0,0 +1,22 @@
+# This succeeds because the ClusterRole allows pods/attach but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_clusteradmin.yaml b/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_clusteradmin.yaml
new file mode 100644
index 00000000..201f8f92
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_clusteradmin.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the ClusterRoleBinding is a default one (by name).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: cluster-admin
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole satisfies the above binding.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: cluster-admin
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "create" ]
+---
+  # This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ "get" ]
diff --git a/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_system-controller-generic-garbage-collector.yaml b/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_system-controller-generic-garbage-collector.yaml
new file mode 100644
index 00000000..fb0023a3
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/success.defaultclusterrolebinding_system-controller-generic-garbage-collector.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the ClusterRoleBinding is a default one (by name).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: system:controller:generic-garbage-collector
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: system:controller:generic-garbage-collector
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole satisfies the above binding.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: system:controller:generic-garbage-collector
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "create" ]
+---
+  # This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ "get" ]
diff --git a/test/checks/clusterrolebindingPodExecAttach/success.exec_wrong_verb.yaml b/test/checks/clusterrolebindingPodExecAttach/success.exec_wrong_verb.yaml
new file mode 100644
index 00000000..6370b0b6
--- /dev/null
+++ b/test/checks/clusterrolebindingPodExecAttach/success.exec_wrong_verb.yaml
@@ -0,0 +1,22 @@
+# This succeeds because the ClusterRole allows pods/exec but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+  name: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolePodExecAttach/failure.all_wildcards.yaml b/test/checks/rolePodExecAttach/failure.all_wildcards.yaml
new file mode 100644
index 00000000..446858f5
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.all_wildcards.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role apiGroups, resources, and verbs are all * which allows pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
diff --git a/test/checks/rolePodExecAttach/failure.attach_explicit.yaml b/test/checks/rolePodExecAttach/failure.attach_explicit.yaml
new file mode 100644
index 00000000..ac385dea
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.attach_explicit.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
diff --git a/test/checks/rolePodExecAttach/failure.attach_using_verb_wildcard.yaml b/test/checks/rolePodExecAttach/failure.attach_using_verb_wildcard.yaml
new file mode 100644
index 00000000..a472ced8
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.attach_using_verb_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "*" ]
diff --git a/test/checks/rolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..7abc4260
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ create ]
diff --git a/test/checks/rolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml b/test/checks/rolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..e32b91ed
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
diff --git a/test/checks/rolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml b/test/checks/rolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..a163dc77
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
diff --git a/test/checks/rolePodExecAttach/failure.exec_explicit.yaml b/test/checks/rolePodExecAttach/failure.exec_explicit.yaml
new file mode 100644
index 00000000..70ea5fcc
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.exec_explicit.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/exec.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
diff --git a/test/checks/rolePodExecAttach/failure.exec_verb_wildcard.yaml b/test/checks/rolePodExecAttach/failure.exec_verb_wildcard.yaml
new file mode 100644
index 00000000..afaa8b58
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.exec_verb_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/exec using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "*" ]
diff --git a/test/checks/rolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..656b7a04
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ get ]
diff --git a/test/checks/rolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml b/test/checks/rolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..e488d523
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ get ]
diff --git a/test/checks/rolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml b/test/checks/rolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..e5e8841a
--- /dev/null
+++ b/test/checks/rolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,10 @@
+# This fails because the Role allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ get ]
diff --git a/test/checks/rolePodExecAttach/success.allow_unrelated_perms.yaml b/test/checks/rolePodExecAttach/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..735362a5
--- /dev/null
+++ b/test/checks/rolePodExecAttach/success.allow_unrelated_perms.yaml
@@ -0,0 +1,10 @@
+# This succeeds because the Role does not allow pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
diff --git a/test/checks/rolePodExecAttach/success.attach_wrong_verb.yaml b/test/checks/rolePodExecAttach/success.attach_wrong_verb.yaml
new file mode 100644
index 00000000..9c9da717
--- /dev/null
+++ b/test/checks/rolePodExecAttach/success.attach_wrong_verb.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the Role allows pods/attach but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ list ]
diff --git a/test/checks/rolePodExecAttach/success.exec_wrong_verb.yaml b/test/checks/rolePodExecAttach/success.exec_wrong_verb.yaml
new file mode 100644
index 00000000..fd5cf9df
--- /dev/null
+++ b/test/checks/rolePodExecAttach/success.exec_wrong_verb.yaml
@@ -0,0 +1,9 @@
+# This succeeds because the Role allows pods/exec but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs.yaml b/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs.yaml
new file mode 100644
index 00000000..6e548295
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a ClusterRole that uses all wildcards and all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs_different_order.yaml b/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs_different_order.yaml
new file mode 100644
index 00000000..248f19aa
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/failure.all_verbs_different_order.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a ClusterRole that uses all wildcards and all verbs (in different order from failure.all_verbs.yaml).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "delete", "update", "create", "patch", "watch" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/failure.default_clusteradmin_clusterrole.yaml b/test/checks/rolebindingClusterAdminClusterRole/failure.default_clusteradmin_clusterrole.yaml
new file mode 100644
index 00000000..4113d2d5
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/failure.default_clusteradmin_clusterrole.yaml
@@ -0,0 +1,31 @@
+# This fails because the roleBinding references the default cluster-admin ClusterRole.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: cluster-admin
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole emulates the default cluster-admin one.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: cluster-admin
+rules:
+- apiGroups:
+  - '*'
+  resources:
+  - '*'
+  verbs:
+  - 'get'
+- nonResourceURLs:
+  - '*'
+  verbs:
+  - '*'
diff --git a/test/checks/rolebindingClusterAdminClusterRole/failure.wildcards.yaml b/test/checks/rolebindingClusterAdminClusterRole/failure.wildcards.yaml
new file mode 100644
index 00000000..9d057eae
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/failure.wildcards.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a ClusterRole that uses all wildcards.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.allow_unrelated_perms.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..c676730c
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/success.allow_unrelated_perms.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the RoleBinding references a ClusterRole with safe permissions.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "deployments" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+  # This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.binding_references_role.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.binding_references_role.yaml
new file mode 100644
index 00000000..99d141b6
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/success.binding_references_role.yaml
@@ -0,0 +1,35 @@
+# This succeeds because the roleBinding references a Role instead of a ClusterRole.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at least one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.explicit_apigroups.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_apigroups.yaml
new file mode 100644
index 00000000..7d2dd351
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_apigroups.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a ClusterRole with a safer subset of apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.explicit_resources.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_resources.yaml
new file mode 100644
index 00000000..52845344
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_resources.yaml
@@ -0,0 +1,35 @@
+# This succeeds because the roleBinding references a ClusterRole with a safer subset of resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
+
diff --git a/test/checks/rolebindingClusterAdminClusterRole/success.explicit_verbs.yaml b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_verbs.yaml
new file mode 100644
index 00000000..7bf63f04
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminClusterRole/success.explicit_verbs.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a ClusterRole with a safer subset of verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+  # This Role exists so there is at least one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/failure.all_verbs.yaml b/test/checks/rolebindingClusterAdminRole/failure.all_verbs.yaml
new file mode 100644
index 00000000..7ccb272d
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/failure.all_verbs.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a Role that uses all wildcards and all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "watch", "create", "update", "patch", "delete" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/failure.all_verbs_different_order.yaml b/test/checks/rolebindingClusterAdminRole/failure.all_verbs_different_order.yaml
new file mode 100644
index 00000000..a009648c
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/failure.all_verbs_different_order.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a Role that uses all wildcards and all verbs (in different order from failure.all_verbs.yaml).
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list", "delete", "update", "create", "patch", "watch" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/failure.wildcards.yaml b/test/checks/rolebindingClusterAdminRole/failure.wildcards.yaml
new file mode 100644
index 00000000..41b46919
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/failure.wildcards.yaml
@@ -0,0 +1,34 @@
+# This fails because the roleBinding references a Role that uses all wildcards.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/success.allow_unrelated_perms.yaml b/test/checks/rolebindingClusterAdminRole/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..d3838e2e
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/success.allow_unrelated_perms.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a Role with safe permissions.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "deployments" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+  # This ClusterRole exists so there is at least one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/success.binding_references_clusterrole.yaml b/test/checks/rolebindingClusterAdminRole/success.binding_references_clusterrole.yaml
new file mode 100644
index 00000000..b748d885
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/success.binding_references_clusterrole.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a ClusterRole instead of a Role.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This Role exists so there is at leat one Role for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: not-used
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/success.explicit_apigroups.yaml b/test/checks/rolebindingClusterAdminRole/success.explicit_apigroups.yaml
new file mode 100644
index 00000000..3df246ab
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/success.explicit_apigroups.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a Role with a safer subset of apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterAdminRole/success.explicit_resources.yaml b/test/checks/rolebindingClusterAdminRole/success.explicit_resources.yaml
new file mode 100644
index 00000000..b041f468
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/success.explicit_resources.yaml
@@ -0,0 +1,35 @@
+# This succeeds because the roleBinding references a Role with a safer subset of resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+# This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
+
diff --git a/test/checks/rolebindingClusterAdminRole/success.explicit_verbs.yaml b/test/checks/rolebindingClusterAdminRole/success.explicit_verbs.yaml
new file mode 100644
index 00000000..a0397180
--- /dev/null
+++ b/test/checks/rolebindingClusterAdminRole/success.explicit_verbs.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a Role with a safer subset of verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "get", "list" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
+---
+  # This ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.all_wildcards.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.all_wildcards.yaml
new file mode 100644
index 00000000..076cf114
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.all_wildcards.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole apiGroups, resources, and verbs are all * which allows pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_explicit.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_explicit.yaml
new file mode 100644
index 00000000..2a64a81f
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_explicit.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_using_verb_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_using_verb_wildcard.yaml
new file mode 100644
index 00000000..0128a02e
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.attach_using_verb_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_points_to_missing_ref.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_points_to_missing_ref.yaml
new file mode 100644
index 00000000..520ca8a0
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.binding_points_to_missing_ref.yaml
@@ -0,0 +1,14 @@
+# This fails because the roleRef points to a ClusterRole that does not exist.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: does-not-exist
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..a1028203
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..475aa542
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..c1661f44
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_explicit.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_explicit.yaml
new file mode 100644
index 00000000..038179bb
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_explicit.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/exec.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_verb_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_verb_wildcard.yaml
new file mode 100644
index 00000000..dad55fcf
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.exec_verb_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/exec using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..c6af9cba
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..c33a99ac
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..9a8182a2
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,23 @@
+# This fails because the ClusterRole allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.allow_unrelated_perms.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..1bdf0dd8
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/success.allow_unrelated_perms.yaml
@@ -0,0 +1,23 @@
+# This succeeds because the ClusterRole does not allow pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.attach_wrong_verb.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.attach_wrong_verb.yaml
new file mode 100644
index 00000000..51fe2390
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/success.attach_wrong_verb.yaml
@@ -0,0 +1,23 @@
+# This succeeds because the ClusterRole allows pods/attach but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.binding_references_role.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.binding_references_role.yaml
new file mode 100644
index 00000000..d4dec6b5
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/success.binding_references_role.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a Role instead of a ClusterRole.
+# THis ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingClusterRolePodExecAttach/success.exec_wrong_verb.yaml b/test/checks/rolebindingClusterRolePodExecAttach/success.exec_wrong_verb.yaml
new file mode 100644
index 00000000..2e175c22
--- /dev/null
+++ b/test/checks/rolebindingClusterRolePodExecAttach/success.exec_wrong_verb.yaml
@@ -0,0 +1,23 @@
+# This succeeds because the ClusterRole allows pods/exec but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: ClusterRole
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.all_wildcards.yaml b/test/checks/rolebindingRolePodExecAttach/failure.all_wildcards.yaml
new file mode 100644
index 00000000..b83f09fc
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.all_wildcards.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role apiGroups, resources, and verbs are all * which allows pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "*" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.attach_explicit.yaml b/test/checks/rolebindingRolePodExecAttach/failure.attach_explicit.yaml
new file mode 100644
index 00000000..1f246b72
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.attach_explicit.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.attach_using_verb_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.attach_using_verb_wildcard.yaml
new file mode 100644
index 00000000..d38c56db
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.attach_using_verb_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.binding_points_to_missing_ref.yaml b/test/checks/rolebindingRolePodExecAttach/failure.binding_points_to_missing_ref.yaml
new file mode 100644
index 00000000..95777c59
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.binding_points_to_missing_ref.yaml
@@ -0,0 +1,14 @@
+# This fails because the roleRef points to a Role that does not exist.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: does-not-exist
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..a6e22bce
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.create_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..e952a862
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.create_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..ee614e35
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.create_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.exec_explicit.yaml b/test/checks/rolebindingRolePodExecAttach/failure.exec_explicit.yaml
new file mode 100644
index 00000000..1de8352b
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.exec_explicit.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/exec.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.exec_verb_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.exec_verb_wildcard.yaml
new file mode 100644
index 00000000..448d5d11
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.exec_verb_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/exec using all verbs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ "*" ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
new file mode 100644
index 00000000..56efc20a
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.get_attach_and_exec_using_resource_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach|exec using all resources.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "*" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..a82320c5
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.get_attach_using_apigroup_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/attach using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/attach" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml b/test/checks/rolebindingRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
new file mode 100644
index 00000000..67bd97da
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/failure.get_exec_using_apigroup_wildcard.yaml
@@ -0,0 +1,24 @@
+# This fails because the Role allows pods/exec using all apiGroups.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "*" ]
+    resources: [ "pods/exec" ]
+    verbs: [ get ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/success.allow_unrelated_perms.yaml b/test/checks/rolebindingRolePodExecAttach/success.allow_unrelated_perms.yaml
new file mode 100644
index 00000000..519a9781
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/success.allow_unrelated_perms.yaml
@@ -0,0 +1,24 @@
+# This succeeds because the Role does not allow pods/exec|attach.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/success.attach_wrong_verb.yaml b/test/checks/rolebindingRolePodExecAttach/success.attach_wrong_verb.yaml
new file mode 100644
index 00000000..37f35d3f
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/success.attach_wrong_verb.yaml
@@ -0,0 +1,24 @@
+# This succeeds because the Role allows pods/attach but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/attach" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/success.binding_references_role.yaml b/test/checks/rolebindingRolePodExecAttach/success.binding_references_role.yaml
new file mode 100644
index 00000000..d4dec6b5
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/success.binding_references_role.yaml
@@ -0,0 +1,34 @@
+# This succeeds because the roleBinding references a Role instead of a ClusterRole.
+# THis ClusterRole exists so there is at leat one ClusterRole for the additionalSchema to find.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: not-used
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods" ]
+    verbs: [ get, create ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/checks/rolebindingRolePodExecAttach/success.exec_wrong_verb.yaml b/test/checks/rolebindingRolePodExecAttach/success.exec_wrong_verb.yaml
new file mode 100644
index 00000000..cc09e09c
--- /dev/null
+++ b/test/checks/rolebindingRolePodExecAttach/success.exec_wrong_verb.yaml
@@ -0,0 +1,24 @@
+# This succeeds because the Role allows pods/exec but with a safe verb.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: Role
+metadata:
+  name: test
+  namespace: test
+rules:
+  - apiGroups: [ "" ]
+    resources: [ "pods/exec" ]
+    verbs: [ list ]
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: RoleBinding
+metadata:
+  name: test
+  namespace: test
+roleRef:
+  apiGroup: rbac.authorization.k8s.io
+  kind: Role
+  name: test
+subjects:
+- apiGroup: rbac.authorization.k8s.io
+  kind: User
+  name: testuser
diff --git a/test/fixtures.go b/test/fixtures.go
index ba7d6c7b..102d8277 100644
--- a/test/fixtures.go
+++ b/test/fixtures.go
@@ -256,6 +256,15 @@ func SetupTestAPI(objects ...runtime.Object) (kubernetes.Interface, dynamic.Inte
 				{Name: "namespaces", Namespaced: false, Kind: "Namespace"},
 			},
 		},
+		{
+			GroupVersion: "rbac.authorization.k8s.io/v1",
+			APIResources: []metav1.APIResource{
+				{Name: "clusterroles", Namespaced: false, Kind: "ClusterRole"},
+				{Name: "roles", Namespaced: true, Kind: "Role"},
+				{Name: "clusterrolebindings", Namespaced: false, Kind: "ClusterRoleBinding"},
+				{Name: "rolebindings", Namespaced: true, Kind: "RoleBinding"},
+			},
+		},
 	}
 	return k, dynamicClient
 }