1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +00:00

remove wildcard permissions (#10785)

* remove wildcard permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update codegen

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* codegen

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix background controller perms

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* remove secrets perm

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update tests

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix reports-controller role

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* add wildcard check and limit generate policy checks based on `synchronize`

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update manifest

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix wildcard check

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* update default QPS and burst for better performance and to prevent test failure

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix perms

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix perms

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix test permissions

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix merge issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

* fix merge issues

Signed-off-by: Jim Bugwadia <jim@nirmata.com>

---------

Signed-off-by: Jim Bugwadia <jim@nirmata.com>
Co-authored-by: Mariam Fahmy <mariam.fahmy@nirmata.com>
This commit is contained in:
Jim Bugwadia 2024-08-20 01:55:32 -07:00 committed by GitHub
parent 0c2a88638b
commit f06399200c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
189 changed files with 2232 additions and 311 deletions

View file

@ -358,6 +358,8 @@ The chart values are organised per component.
| admissionController.featuresOverride | object | `{"admissionReports":{"backPressureThreshold":1000}}` | Overrides features defined at the root level |
| admissionController.featuresOverride.admissionReports.backPressureThreshold | int | `1000` | Max number of admission reports allowed in flight until the admission controller stops creating new ones |
| admissionController.rbac.create | bool | `true` | Create RBAC resources |
| admissionController.rbac.createViewRoleBinding | bool | `true` | Create rolebinding to view role |
| admissionController.rbac.viewRoleName | string | `"view"` | The view role to use in the rolebinding |
| admissionController.rbac.serviceAccount.name | string | `nil` | The ServiceAccount name |
| admissionController.rbac.serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
| admissionController.rbac.coreClusterRole.extraResources | list | See [values.yaml](values.yaml) | Extra resource permissions to add in the core cluster role. This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`. |
@ -454,6 +456,8 @@ The chart values are organised per component.
| backgroundController.featuresOverride | object | `{}` | Overrides features defined at the root level |
| backgroundController.enabled | bool | `true` | Enable background controller. |
| backgroundController.rbac.create | bool | `true` | Create RBAC resources |
| backgroundController.rbac.createViewRoleBinding | bool | `true` | Create rolebinding to view role |
| backgroundController.rbac.viewRoleName | string | `"view"` | The view role to use in the rolebinding |
| backgroundController.rbac.serviceAccount.name | string | `nil` | Service account name |
| backgroundController.rbac.serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
| backgroundController.rbac.coreClusterRole.extraResources | list | See [values.yaml](values.yaml) | Extra resource permissions to add in the core cluster role. This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`. |
@ -606,6 +610,8 @@ The chart values are organised per component.
| reportsController.featuresOverride | object | `{}` | Overrides features defined at the root level |
| reportsController.enabled | bool | `true` | Enable reports controller. |
| reportsController.rbac.create | bool | `true` | Create RBAC resources |
| reportsController.rbac.createViewRoleBinding | bool | `true` | Create rolebinding to view role |
| reportsController.rbac.viewRoleName | string | `"view"` | The view role to use in the rolebinding |
| reportsController.rbac.serviceAccount.name | string | `nil` | Service account name |
| reportsController.rbac.serviceAccount.annotations | object | `{}` | Annotations for the ServiceAccount |
| reportsController.rbac.coreClusterRole.extraResources | list | See [values.yaml](values.yaml) | Extra resource permissions to add in the core cluster role. This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`. |

View file

@ -7,6 +7,8 @@ metadata:
{{- include "kyverno.admission-controller.labels" . | nindent 4 }}
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-admission-controller: "true"
- matchLabels:
{{- include "kyverno.admission-controller.matchLabels" . | nindent 8 }}
---

View file

@ -13,4 +13,21 @@ subjects:
- kind: ServiceAccount
name: {{ template "kyverno.admission-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- if .Values.admissionController.rbac.createViewRoleBinding }}
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "kyverno.admission-controller.roleName" . }}:view
labels:
{{- include "kyverno.admission-controller.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.admissionController.rbac.viewRoleName }}
subjects:
- kind: ServiceAccount
name: {{ template "kyverno.admission-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- end -}}
{{- end -}}

View file

@ -131,6 +131,7 @@ spec:
- --caSecretName={{ template "kyverno.admission-controller.serviceName" . }}.{{ template "kyverno.namespace" . }}.svc.kyverno-tls-ca
- --tlsSecretName={{ template "kyverno.admission-controller.serviceName" . }}.{{ template "kyverno.namespace" . }}.svc.kyverno-tls-pair
- --backgroundServiceAccountName=system:serviceaccount:{{ include "kyverno.namespace" . }}:{{ include "kyverno.background-controller.serviceAccountName" . }}
- --reportsServiceAccountName=system:serviceaccount:{{ include "kyverno.namespace" . }}:{{ include "kyverno.reports-controller.serviceAccountName" . }}
- --servicePort={{ .Values.admissionController.service.port }}
- --webhookServerPort={{ .Values.admissionController.webhookServer.port }}
{{- if .Values.admissionController.tracing.enabled }}

View file

@ -8,6 +8,8 @@ metadata:
{{- include "kyverno.background-controller.labels" . | nindent 4 }}
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
- matchLabels:
{{- include "kyverno.background-controller.matchLabels" . | nindent 8 }}
---
@ -28,7 +30,9 @@ rules:
- kyverno.io
resources:
- policies
- policies/status
- clusterpolicies
- clusterpolicies/status
- policyexceptions
- updaterequests
- updaterequests/status

View file

@ -11,8 +11,25 @@ roleRef:
kind: ClusterRole
name: {{ template "kyverno.background-controller.roleName" . }}
subjects:
- kind: ServiceAccount
name: {{ template "kyverno.background-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- if .Values.backgroundController.rbac.createViewRoleBinding }}
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "kyverno.background-controller.roleName" . }}:view
labels:
{{- include "kyverno.background-controller.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.backgroundController.rbac.viewRoleName }}
subjects:
- kind: ServiceAccount
name: {{ template "kyverno.background-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- end -}}
{{- end -}}
{{- end -}}

View file

@ -8,6 +8,8 @@ metadata:
{{- include "kyverno.cleanup-controller.labels" . | nindent 4 }}
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-cleanup-controller: "true"
- matchLabels:
{{- include "kyverno.cleanup-controller.matchLabels" . | nindent 8 }}
---

View file

@ -8,6 +8,8 @@ metadata:
{{- include "kyverno.reports-controller.labels" . | nindent 4 }}
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-reports-controller: "true"
- matchLabels:
{{- include "kyverno.reports-controller.matchLabels" . | nindent 8 }}
---
@ -27,7 +29,6 @@ rules:
- apiGroups:
- ''
resources:
- secrets
- configmaps
- namespaces
verbs:

View file

@ -11,8 +11,25 @@ roleRef:
kind: ClusterRole
name: {{ template "kyverno.reports-controller.roleName" . }}
subjects:
- kind: ServiceAccount
name: {{ template "kyverno.reports-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- if .Values.reportsController.rbac.createViewRoleBinding }}
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ template "kyverno.reports-controller.roleName" . }}:view
labels:
{{- include "kyverno.reports-controller.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ .Values.reportsController.rbac.viewRoleName }}
subjects:
- kind: ServiceAccount
name: {{ template "kyverno.reports-controller.serviceAccountName" . }}
namespace: {{ template "kyverno.namespace" . }}
{{- end -}}
{{- end -}}
{{- end -}}

View file

@ -19,6 +19,14 @@ rules:
resourceNames:
- {{ include "kyverno.config.configMapName" . }}
- {{ include "kyverno.config.metricsConfigMapName" . }}
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:

View file

@ -697,6 +697,12 @@ admissionController:
# -- Create RBAC resources
create: true
# -- Create rolebinding to view role
createViewRoleBinding: true
# -- The view role to use in the rolebinding
viewRoleName: view
serviceAccount:
# -- The ServiceAccount name
name:
@ -709,15 +715,7 @@ admissionController:
# -- Extra resource permissions to add in the core cluster role.
# This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`.
# @default -- See [values.yaml](values.yaml)
extraResources:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
extraResources: []
clusterRole:
# -- Extra resource permissions to add in the cluster role
@ -1108,6 +1106,12 @@ backgroundController:
# -- Create RBAC resources
create: true
# -- Create rolebinding to view role
createViewRoleBinding: true
# -- The view role to use in the rolebinding
viewRoleName: view
serviceAccount:
# -- Service account name
name:
@ -1121,14 +1125,6 @@ backgroundController:
# This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`.
# @default -- See [values.yaml](values.yaml)
extraResources:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
@ -1154,7 +1150,6 @@ backgroundController:
- ''
resources:
- configmaps
- secrets
- resourcequotas
- limitranges
verbs:
@ -1718,6 +1713,12 @@ reportsController:
# -- Create RBAC resources
create: true
# -- Create rolebinding to view role
createViewRoleBinding: true
# -- The view role to use in the rolebinding
viewRoleName: view
serviceAccount:
# -- Service account name
name:
@ -1730,15 +1731,7 @@ reportsController:
# -- Extra resource permissions to add in the core cluster role.
# This was introduced to avoid breaking change in the chart but should ideally be moved in `clusterRole.extraResources`.
# @default -- See [values.yaml](values.yaml)
extraResources:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
extraResources: []
clusterRole:
# -- Extra resource permissions to add in the cluster role

View file

@ -273,7 +273,8 @@ func (c *ApplyCommandConfig) applyPolicytoResource(
validPolicies := make([]kyvernov1.PolicyInterface, 0, len(policies))
for _, pol := range policies {
// TODO we should return this info to the caller
_, err := policyvalidation.Validate(pol, nil, nil, nil, true, config.KyvernoUserName(config.KyvernoServiceAccountName()))
sa := config.KyvernoUserName(config.KyvernoServiceAccountName())
_, err := policyvalidation.Validate(pol, nil, nil, nil, true, sa, sa)
if err != nil {
log.Log.Error(err, "policy validation error")
rc.IncrementError(1)

View file

@ -40,7 +40,8 @@ func (o options) execute(ctx context.Context, dir string, keychain authn.Keychai
return fmt.Errorf("unable to read policy file or directory %s (%w)", dir, err)
}
for _, policy := range results.Policies {
if _, err := policyvalidation.Validate(policy, nil, nil, nil, true, config.KyvernoUserName(config.KyvernoServiceAccountName())); err != nil {
sa := config.KyvernoUserName(config.KyvernoServiceAccountName())
if _, err := policyvalidation.Validate(policy, nil, nil, nil, true, sa, sa); err != nil {
return fmt.Errorf("validating policy %s: %v", policy.GetName(), err)
}
}

View file

@ -153,7 +153,8 @@ func runTest(out io.Writer, testCase test.TestCase, registryAccess bool) ([]engi
validPolicies := make([]kyvernov1.PolicyInterface, 0, len(results.Policies))
for _, pol := range results.Policies {
// TODO we should return this info to the caller
_, err := policyvalidation.Validate(pol, nil, nil, nil, true, config.KyvernoUserName(config.KyvernoServiceAccountName()))
sa := config.KyvernoUserName(config.KyvernoServiceAccountName())
_, err := policyvalidation.Validate(pol, nil, nil, nil, true, sa, sa)
if err != nil {
log.Log.Error(err, "skipping invalid policy", "name", pol.GetName())
continue

View file

@ -144,8 +144,8 @@ type options struct {
func newOptions() options {
return options{
clientRateLimitQPS: 20,
clientRateLimitBurst: 50,
clientRateLimitQPS: 100,
clientRateLimitBurst: 200,
eventsRateLimitQPS: 1000,
eventsRateLimitBurst: 2000,
}

View file

@ -247,6 +247,7 @@ func main() {
servicePort int
webhookServerPort int
backgroundServiceAccountName string
reportsServiceAccountName string
maxAPICallResponseLength int64
renewBefore time.Duration
maxAuditWorkers int
@ -267,7 +268,8 @@ func main() {
flagset.BoolVar(&admissionReports, "admissionReports", true, "Enable or disable admission reports.")
flagset.IntVar(&servicePort, "servicePort", 443, "Port used by the Kyverno Service resource and for webhook configurations.")
flagset.IntVar(&webhookServerPort, "webhookServerPort", 9443, "Port used by the webhook server.")
flagset.StringVar(&backgroundServiceAccountName, "backgroundServiceAccountName", "", "Background service account name.")
flagset.StringVar(&backgroundServiceAccountName, "backgroundServiceAccountName", "", "Background controller service account name.")
flagset.StringVar(&reportsServiceAccountName, "reportsServiceAccountName", "", "Reports controller service account name.")
flagset.StringVar(&caSecretName, "caSecretName", "", "Name of the secret containing CA.")
flagset.StringVar(&tlsSecretName, "tlsSecretName", "", "Name of the secret containing TLS pair.")
flagset.Int64Var(&maxAPICallResponseLength, "maxAPICallResponseLength", 10*1000*1000, "Configure the value of maximum allowed GET response size from API Calls")
@ -516,6 +518,7 @@ func main() {
setup.KyvernoDynamicClient,
setup.KyvernoClient,
backgroundServiceAccountName,
reportsServiceAccountName,
)
ephrs, err := StartAdmissionReportsCounter(signalCtx, setup.MetadataClient)
if err != nil {
@ -544,6 +547,7 @@ func main() {
eventGenerator,
admissionReports,
backgroundServiceAccountName,
reportsServiceAccountName,
setup.Jp,
maxAuditWorkers,
maxAuditCapacity,

View file

@ -47215,6 +47215,8 @@ metadata:
app.kubernetes.io/version: latest
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-admission-controller: "true"
- matchLabels:
app.kubernetes.io/component: admission-controller
app.kubernetes.io/instance: kyverno
@ -47346,14 +47348,6 @@ rules:
- get
- list
- watch
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@ -47366,6 +47360,8 @@ metadata:
app.kubernetes.io/version: latest
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
- matchLabels:
app.kubernetes.io/component: background-controller
app.kubernetes.io/instance: kyverno
@ -47391,7 +47387,9 @@ rules:
- kyverno.io
resources:
- policies
- policies/status
- clusterpolicies
- clusterpolicies/status
- policyexceptions
- updaterequests
- updaterequests/status
@ -47427,14 +47425,6 @@ rules:
- patch
- update
- watch
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
- apiGroups:
- networking.k8s.io
resources:
@ -47460,7 +47450,6 @@ rules:
- ""
resources:
- configmaps
- secrets
- resourcequotas
- limitranges
verbs:
@ -47480,6 +47469,8 @@ metadata:
app.kubernetes.io/version: latest
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-cleanup-controller: "true"
- matchLabels:
app.kubernetes.io/component: cleanup-controller
app.kubernetes.io/instance: kyverno
@ -47770,6 +47761,8 @@ metadata:
app.kubernetes.io/version: latest
aggregationRule:
clusterRoleSelectors:
- matchLabels:
rbac.kyverno.io/aggregate-to-reports-controller: "true"
- matchLabels:
app.kubernetes.io/component: reports-controller
app.kubernetes.io/instance: kyverno
@ -47794,7 +47787,6 @@ rules:
- apiGroups:
- ''
resources:
- secrets
- configmaps
- namespaces
verbs:
@ -47856,14 +47848,6 @@ rules:
verbs:
- create
- patch
- apiGroups:
- '*'
resources:
- '*'
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
@ -47885,6 +47869,24 @@ subjects:
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kyverno:admission-controller:view
labels:
app.kubernetes.io/component: admission-controller
app.kubernetes.io/instance: kyverno
app.kubernetes.io/part-of: kyverno
app.kubernetes.io/version: latest
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: kyverno-admission-controller
namespace: kyverno
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kyverno:background-controller
labels:
@ -47903,6 +47905,24 @@ subjects:
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kyverno:background-controller:view
labels:
app.kubernetes.io/component: background-controller
app.kubernetes.io/instance: kyverno
app.kubernetes.io/part-of: kyverno
app.kubernetes.io/version: latest
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: kyverno-background-controller
namespace: kyverno
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kyverno:cleanup-controller
labels:
@ -47937,6 +47957,24 @@ subjects:
name: kyverno-reports-controller
namespace: kyverno
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: kyverno:reports-controller:view
labels:
app.kubernetes.io/component: reports-controller
app.kubernetes.io/instance: kyverno
app.kubernetes.io/part-of: kyverno
app.kubernetes.io/version: latest
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: view
subjects:
- kind: ServiceAccount
name: kyverno-reports-controller
namespace: kyverno
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
@ -48119,6 +48157,14 @@ rules:
resourceNames:
- kyverno
- kyverno-metrics
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- coordination.k8s.io
resources:
@ -48441,6 +48487,7 @@ spec:
- --caSecretName=kyverno-svc.kyverno.svc.kyverno-tls-ca
- --tlsSecretName=kyverno-svc.kyverno.svc.kyverno-tls-pair
- --backgroundServiceAccountName=system:serviceaccount:kyverno:kyverno-background-controller
- --reportsServiceAccountName=system:serviceaccount:kyverno:kyverno-reports-controller
- --servicePort=443
- --webhookServerPort=9443
- --disableMetrics=false

View file

@ -2,22 +2,21 @@ package auth
import (
"context"
"fmt"
"strings"
"github.com/go-logr/logr"
"github.com/kyverno/kyverno/pkg/auth"
"github.com/kyverno/kyverno/pkg/clients/dclient"
)
// Operations provides methods to performing operations on resource
type Operations interface {
// CanICreate returns 'true' if self can 'create' resource
CanICreate(ctx context.Context, gvk, namespace, name, subresource string) (bool, error)
// CanIUpdate returns 'true' if self can 'update' resource
CanIUpdate(ctx context.Context, gvk, namespace, name, subresource string) (bool, error)
// CanIDelete returns 'true' if self can 'delete' resource
CanIDelete(ctx context.Context, gvk, namespace, name, subresource string) (bool, error)
// CanIGet returns 'true' if self can 'get' resource
CanIGet(ctx context.Context, gvk, namespace, name, subresource string) (bool, error)
// AuthChecks provides methods to performing operations on resource
type AuthChecks interface {
// User returns the subject
User() string
// CanI returns 'true' if user has permissions for all specified verbs.
// When the result is 'false' a message with details on missing verbs is returned.
CanI(ctx context.Context, verbs []string, gvk, namespace, name, subresource string) (bool, string, error)
}
// Auth provides implementation to check if caller/self/kyverno has access to perofrm operations
@ -37,9 +36,36 @@ func NewAuth(client dclient.Interface, user string, log logr.Logger) *Auth {
return &a
}
func (a *Auth) User() string {
return a.user
}
func (a *Auth) CanI(ctx context.Context, verbs []string, gvk, namespace, name, subresource string) (bool, string, error) {
var failedVerbs []string
for _, v := range verbs {
if ok, err := a.check(ctx, v, gvk, namespace, name, subresource); err != nil {
return false, "", err
} else if !ok {
failedVerbs = append(failedVerbs, v)
}
}
if len(failedVerbs) > 0 {
msg := buildMessage(gvk, subresource, failedVerbs, a.user, namespace)
return false, msg, nil
}
return true, "", nil
}
// CanICreate returns 'true' if self can 'create' resource
func (a *Auth) CanICreate(ctx context.Context, gvk, namespace, name, subresource string) (bool, error) {
canI := auth.NewCanI(a.client.Discovery(), a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews(), gvk, namespace, name, "create", "", a.user)
return a.check(ctx, "create", gvk, namespace, name, subresource)
}
func (a *Auth) check(ctx context.Context, verb, gvk, namespace, name, subresource string) (bool, error) {
subjectReview := a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews()
canI := auth.NewCanI(a.client.Discovery(), subjectReview, gvk, namespace, name, verb, subresource, a.user)
ok, _, err := canI.RunAccessCheck(ctx)
if err != nil {
return false, err
@ -47,32 +73,16 @@ func (a *Auth) CanICreate(ctx context.Context, gvk, namespace, name, subresource
return ok, nil
}
// CanIUpdate returns 'true' if self can 'update' resource
func (a *Auth) CanIUpdate(ctx context.Context, gvk, namespace, name, subresource string) (bool, error) {
canI := auth.NewCanI(a.client.Discovery(), a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews(), gvk, namespace, name, "update", "", a.user)
ok, _, err := canI.RunAccessCheck(ctx)
if err != nil {
return false, err
func buildMessage(gvk string, subresource string, failedVerbs []string, user string, namespace string) string {
resource := gvk
if subresource != "" {
resource = gvk + "/" + subresource
}
return ok, nil
}
// CanIDelete returns 'true' if self can 'delete' resource
func (a *Auth) CanIDelete(ctx context.Context, gvk, namespace, name, subresource string) (bool, error) {
canI := auth.NewCanI(a.client.Discovery(), a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews(), gvk, namespace, name, "delete", "", a.user)
ok, _, err := canI.RunAccessCheck(ctx)
if err != nil {
return false, err
permissions := strings.Join(failedVerbs, ",")
msg := fmt.Sprintf("%s requires permissions %s for resource %s", user, permissions, resource)
if namespace != "" {
msg = fmt.Sprintf("%s in namespace %s", msg, namespace)
}
return ok, nil
}
// CanIGet returns 'true' if self can 'get' resource
func (a *Auth) CanIGet(ctx context.Context, gvk, namespace, name, subresource string) (bool, error) {
canI := auth.NewCanI(a.client.Discovery(), a.client.GetKubeClient().AuthorizationV1().SubjectAccessReviews(), gvk, namespace, name, "get", "", a.user)
ok, _, err := canI.RunAccessCheck(ctx)
if err != nil {
return false, err
}
return ok, nil
return msg
}

View file

@ -11,6 +11,14 @@ func NewFakeAuth() *FakeAuth {
return &a
}
func (a *FakeAuth) User() string {
return "fake"
}
func (a *FakeAuth) CanI(ctx context.Context, verbs []string, gvk, namespace, name, subresource string) (bool, string, error) {
return true, "", nil
}
// CanICreate returns 'true'
func (a *FakeAuth) CanICreate(_ context.Context, kind, namespace, name, sub string) (bool, error) {
return true, nil

View file

@ -17,7 +17,7 @@ type FakeGenerate struct {
func NewFakeGenerate(rule kyvernov1.Generation) *FakeGenerate {
g := FakeGenerate{}
g.rule = rule
g.authCheck = fake.NewFakeAuth()
g.authChecker = fake.NewFakeAuth()
g.log = logging.GlobalLogger()
return &g
}

View file

@ -17,33 +17,30 @@ import (
// Generate provides implementation to validate 'generate' rule
type Generate struct {
user string
// rule to hold 'generate' rule specifications
rule kyvernov1.Generation
// authCheck to check access for operations
authCheck auth.Operations
// logger
log logr.Logger
user string
rule kyvernov1.Generation
authChecker auth.AuthChecks
log logr.Logger
}
// NewGenerateFactory returns a new instance of Generate validation checker
func NewGenerateFactory(client dclient.Interface, rule kyvernov1.Generation, user string, log logr.Logger) *Generate {
g := Generate{
user: user,
rule: rule,
authCheck: auth.NewAuth(client, user, log),
log: log,
user: user,
rule: rule,
authChecker: auth.NewAuth(client, user, log),
log: log,
}
return &g
}
// Validate validates the 'generate' rule
func (g *Generate) Validate(ctx context.Context) (string, error) {
func (g *Generate) Validate(ctx context.Context) (warnings []string, path string, err error) {
rule := g.rule
if rule.CloneList.Selector != nil {
if wildcard.ContainsWildcard(rule.CloneList.Selector.String()) {
return "selector", fmt.Errorf("wildcard characters `*/?` not supported")
return nil, "selector", fmt.Errorf("wildcard characters `*/?` not supported")
}
}
@ -51,7 +48,7 @@ func (g *Generate) Validate(ctx context.Context) (string, error) {
// TODO: is this required ?? as anchors can only be on pattern and not resource
// we can add this check by not sure if its needed here
if path, err := common.ValidatePattern(target, "/", nil); err != nil {
return fmt.Sprintf("data.%s", path), fmt.Errorf("anchors not supported on generate resources: %v", err)
return nil, fmt.Sprintf("data.%s", path), fmt.Errorf("anchors not supported on generate resources: %v", err)
}
}
@ -62,19 +59,20 @@ func (g *Generate) Validate(ctx context.Context) (string, error) {
// If kind and namespace contain variables, then we cannot resolve then so we skip the processing
if rule.ForEachGeneration != nil {
for _, forEach := range rule.ForEachGeneration {
if err := g.canIGeneratePatterns(ctx, forEach.GeneratePatterns); err != nil {
return "foreach", err
if err := g.validateAuth(ctx, forEach.GeneratePatterns); err != nil {
return nil, "foreach", err
}
}
} else {
if err := g.canIGeneratePatterns(ctx, rule.GeneratePatterns); err != nil {
return "", err
if err := g.validateAuth(ctx, rule.GeneratePatterns); err != nil {
return nil, "", err
}
}
return "", nil
return nil, "", nil
}
func (g *Generate) canIGeneratePatterns(ctx context.Context, generate kyvernov1.GeneratePatterns) error {
// validateAuth returns a error if kyverno cannot perform operations
func (g *Generate) validateAuth(ctx context.Context, generate kyvernov1.GeneratePatterns) error {
if len(generate.CloneList.Kinds) != 0 {
for _, kind := range generate.CloneList.Kinds {
gvk, sub := parseCloneKind(kind)
@ -87,44 +85,24 @@ func (g *Generate) canIGeneratePatterns(ctx context.Context, generate kyvernov1.
return nil
}
// canIGenerate returns a error if kyverno cannot perform operations
func (g *Generate) canIGenerate(ctx context.Context, gvk, namespace, subresource string) error {
// Skip if there is variable defined
authCheck := g.authCheck
if !regex.IsVariable(gvk) {
ok, err := authCheck.CanICreate(ctx, gvk, namespace, "", subresource)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("%s does not have permissions to 'create' resource %s/%s/%s. Grant proper permissions to the background controller", g.user, gvk, subresource, namespace)
}
if regex.IsVariable(gvk) {
g.log.V(2).Info("resource Kind uses variables; skipping authorization checks.")
return nil
}
ok, err = authCheck.CanIUpdate(ctx, gvk, namespace, "", subresource)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("%s does not have permissions to 'update' resource %s/%s/%s. Grant proper permissions to the background controller", g.user, gvk, subresource, namespace)
}
verbs := []string{"get", "create"}
if g.rule.Synchronize {
verbs = []string{"get", "create", "update", "delete"}
}
ok, err = authCheck.CanIGet(ctx, gvk, namespace, "", subresource)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("%s does not have permissions to 'get' resource %s/%s/%s. Grant proper permissions to the background controller", g.user, gvk, subresource, namespace)
}
ok, msg, err := g.authChecker.CanI(ctx, verbs, gvk, namespace, "", subresource)
if err != nil {
return err
}
ok, err = authCheck.CanIDelete(ctx, gvk, namespace, "", subresource)
if err != nil {
return err
}
if !ok {
return fmt.Errorf("%s does not have permissions to 'delete' resource %s/%s/%s. Grant proper permissions to the background controller", g.user, gvk, subresource, namespace)
}
} else {
g.log.V(2).Info("resource Kind uses variables, so cannot be resolved. Skipping Auth Checks.")
if !ok {
return fmt.Errorf(msg)
}
return nil

View file

@ -36,7 +36,7 @@ func Test_Validate_Generate_HasAnchors(t *testing.T) {
err = json.Unmarshal(rawGenerate, &genRule)
assert.NilError(t, err)
checker := NewFakeGenerate(genRule)
if _, err := checker.Validate(context.TODO()); err != nil {
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
@ -53,7 +53,7 @@ func Test_Validate_Generate_HasAnchors(t *testing.T) {
err = json.Unmarshal(rawGenerate, &genRule)
assert.NilError(t, err)
checker = NewFakeGenerate(genRule)
if _, err := checker.Validate(context.TODO()); err != nil {
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}

View file

@ -6,8 +6,11 @@ import (
"strings"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/engine/variables/regex"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/policy/auth"
"github.com/kyverno/kyverno/pkg/policy/auth/fake"
kubeutils "github.com/kyverno/kyverno/pkg/utils/kube"
"go.uber.org/multierr"
)
@ -15,48 +18,53 @@ import (
// Mutate provides implementation to validate 'mutate' rule
type Mutate struct {
mutation kyvernov1.Mutation
user string
authChecker auth.Operations
authChecker auth.AuthChecks
}
// NewMutateFactory returns a new instance of Mutate validation checker
func NewMutateFactory(m kyvernov1.Mutation, authChecker auth.Operations, user string) *Mutate {
func NewMutateFactory(m kyvernov1.Mutation, client dclient.Interface, mock bool, backgroundSA string) *Mutate {
var authCheck auth.AuthChecks
if mock {
authCheck = fake.NewFakeAuth()
} else {
authCheck = auth.NewAuth(client, backgroundSA, logging.GlobalLogger())
}
return &Mutate{
mutation: m,
user: user,
authChecker: authChecker,
authChecker: authCheck,
}
}
// Validate validates the 'mutate' rule
func (m *Mutate) Validate(ctx context.Context) (string, error) {
func (m *Mutate) Validate(ctx context.Context) (warnings []string, path string, err error) {
if m.hasForEach() {
if m.hasPatchStrategicMerge() || m.hasPatchesJSON6902() {
return "foreach", fmt.Errorf("only one of `foreach`, `patchStrategicMerge`, or `patchesJson6902` is allowed")
return nil, "foreach", fmt.Errorf("only one of `foreach`, `patchStrategicMerge`, or `patchesJson6902` is allowed")
}
return m.validateForEach("", m.mutation.ForEachMutation)
}
if m.hasPatchesJSON6902() && m.hasPatchStrategicMerge() {
return "foreach", fmt.Errorf("only one of `patchStrategicMerge` or `patchesJson6902` is allowed")
return nil, "foreach", fmt.Errorf("only one of `patchStrategicMerge` or `patchesJson6902` is allowed")
}
if m.mutation.Targets != nil {
if err := m.validateAuth(ctx, m.mutation.Targets); err != nil {
return "targets", fmt.Errorf("auth check fails, additional privileges are required for the service account '%s': %v", m.user, err)
return nil, "targets", fmt.Errorf("auth check fails, additional privileges are required for the service account '%s': %v", m.authChecker.User(), err)
}
}
return "", nil
return nil, "", nil
}
func (m *Mutate) validateForEach(tag string, foreach []kyvernov1.ForEachMutation) (string, error) {
func (m *Mutate) validateForEach(tag string, foreach []kyvernov1.ForEachMutation) (warnings []string, path string, err error) {
for i, fe := range foreach {
tag = tag + fmt.Sprintf("foreach[%d]", i)
fem := fe.GetForEachMutation()
if len(fem) > 0 {
if fe.Context != nil || fe.AnyAllConditions != nil || fe.PatchesJSON6902 != "" || fe.GetPatchStrategicMerge() != nil {
return tag, fmt.Errorf("a nested foreach cannot contain other declarations")
if fe.Context != nil || fe.AnyAllConditions != nil || fe.PatchesJSON6902 != "" || fe.RawPatchStrategicMerge != nil {
return nil, tag, fmt.Errorf("a nested foreach cannot contain other declarations")
}
return m.validateNestedForEach(tag, fem)
@ -64,19 +72,19 @@ func (m *Mutate) validateForEach(tag string, foreach []kyvernov1.ForEachMutation
psm := fe.GetPatchStrategicMerge()
if (fe.PatchesJSON6902 == "" && psm == nil) || (fe.PatchesJSON6902 != "" && psm != nil) {
return tag, fmt.Errorf("only one of `patchStrategicMerge` or `patchesJson6902` is allowed")
return nil, tag, fmt.Errorf("only one of `patchStrategicMerge` or `patchesJson6902` is allowed")
}
}
return "", nil
return nil, "", nil
}
func (m *Mutate) validateNestedForEach(tag string, j []kyvernov1.ForEachMutation) (string, error) {
func (m *Mutate) validateNestedForEach(tag string, j []kyvernov1.ForEachMutation) (warnings []string, path string, err error) {
if j != nil {
return m.validateForEach(tag, j)
}
return "", nil
return nil, "", nil
}
func (m *Mutate) hasForEach() bool {
@ -94,25 +102,20 @@ func (m *Mutate) hasPatchesJSON6902() bool {
func (m *Mutate) validateAuth(ctx context.Context, targets []kyvernov1.TargetResourceSpec) error {
var errs []error
for _, target := range targets {
if !regex.IsVariable(target.Kind) {
_, _, k, sub := kubeutils.ParseKindSelector(target.Kind)
srcKey := k
if sub != "" {
srcKey = srcKey + "/" + sub
}
if ok, err := m.authChecker.CanIUpdate(ctx, strings.Join([]string{target.APIVersion, k}, "/"), target.Namespace, target.Name, sub); err != nil {
errs = append(errs, err)
} else if !ok {
errs = append(errs, fmt.Errorf("cannot %s/%s/%s in namespace %s", "update", target.APIVersion, srcKey, target.Namespace))
}
if ok, err := m.authChecker.CanIGet(ctx, strings.Join([]string{target.APIVersion, k}, "/"), target.Namespace, target.Name, sub); err != nil {
errs = append(errs, err)
} else if !ok {
errs = append(errs, fmt.Errorf("cannot %s/%s/%s in namespace %s", "get", target.APIVersion, srcKey, target.Namespace))
}
if regex.IsVariable(target.Kind) {
continue
}
_, _, k, sub := kubeutils.ParseKindSelector(target.Kind)
gvk := strings.Join([]string{target.APIVersion, k}, "/")
verbs := []string{"get", "update"}
ok, msg, err := m.authChecker.CanI(ctx, verbs, gvk, target.Namespace, target.Name, sub)
if err != nil {
return err
}
if !ok {
errs = append(errs, fmt.Errorf(msg))
}
}
return multierr.Combine(errs...)
}

View file

@ -5,32 +5,53 @@ import (
"fmt"
kyvernov1 "github.com/kyverno/kyverno/api/kyverno/v1"
"github.com/kyverno/kyverno/ext/wildcard"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/engine/anchor"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/policy/auth"
"github.com/kyverno/kyverno/pkg/policy/auth/fake"
"github.com/kyverno/kyverno/pkg/policy/common"
)
// Validate validates a 'validate' rule
type Validate struct {
// rule to hold 'validate' rule specifications
rule *kyvernov1.Validation
rule *kyvernov1.Rule
validationRule *kyvernov1.Validation
authChecker auth.AuthChecks
}
// NewValidateFactory returns a new instance of Mutate validation checker
func NewValidateFactory(rule *kyvernov1.Validation) *Validate {
m := Validate{
rule: rule,
func NewValidateFactory(rule *kyvernov1.Rule, client dclient.Interface, mock bool, reportsSA string) *Validate {
var authChecker auth.AuthChecks
if mock {
authChecker = fake.NewFakeAuth()
} else {
authChecker = auth.NewAuth(client, reportsSA, logging.GlobalLogger())
}
return &m
return &Validate{
rule: rule,
validationRule: &rule.Validation,
authChecker: authChecker,
}
}
func NewMockValidateFactory(rule *kyvernov1.Rule) *Validate {
return &Validate{
rule: rule,
validationRule: &rule.Validation,
authChecker: fake.NewFakeAuth(),
}
}
// Validate validates the 'validate' rule
func (v *Validate) Validate(ctx context.Context) (string, error) {
func (v *Validate) Validate(ctx context.Context) (warnings []string, path string, err error) {
if err := v.validateElements(); err != nil {
return "", err
return nil, "", err
}
if target := v.rule.GetPattern(); target != nil {
if target := v.validationRule.GetPattern(); target != nil {
if path, err := common.ValidatePattern(target, "/", func(a anchor.Anchor) bool {
return anchor.IsCondition(a) ||
anchor.IsExistence(a) ||
@ -38,14 +59,14 @@ func (v *Validate) Validate(ctx context.Context) (string, error) {
anchor.IsNegation(a) ||
anchor.IsGlobal(a)
}); err != nil {
return fmt.Sprintf("pattern.%s", path), err
return nil, fmt.Sprintf("pattern.%s", path), err
}
}
if target := v.rule.GetAnyPattern(); target != nil {
anyPattern, err := v.rule.DeserializeAnyPattern()
if target := v.validationRule.GetAnyPattern(); target != nil {
anyPattern, err := v.validationRule.DeserializeAnyPattern()
if err != nil {
return "anyPattern", fmt.Errorf("failed to deserialize anyPattern, expect array: %v", err)
return nil, "anyPattern", fmt.Errorf("failed to deserialize anyPattern, expect array: %v", err)
}
for i, pattern := range anyPattern {
if path, err := common.ValidatePattern(pattern, "/", func(a anchor.Anchor) bool {
@ -55,76 +76,102 @@ func (v *Validate) Validate(ctx context.Context) (string, error) {
anchor.IsNegation(a) ||
anchor.IsGlobal(a)
}); err != nil {
return fmt.Sprintf("anyPattern[%d].%s", i, path), err
return nil, fmt.Sprintf("anyPattern[%d].%s", i, path), err
}
}
}
if v.rule.ForEachValidation != nil {
for _, foreach := range v.rule.ForEachValidation {
if v.validationRule.ForEachValidation != nil {
for _, foreach := range v.validationRule.ForEachValidation {
if err := v.validateForEach(foreach); err != nil {
return "", err
return nil, "", err
}
}
}
if v.rule.CEL != nil {
for _, expression := range v.rule.CEL.Expressions {
if v.validationRule.CEL != nil {
for _, expression := range v.validationRule.CEL.Expressions {
if expression.Expression == "" {
return "", fmt.Errorf("cel.expressions.expression is required")
return nil, "", fmt.Errorf("cel.expressions.expression is required")
}
}
if v.rule.CEL.ParamKind != nil {
if v.rule.CEL.ParamKind.APIVersion == "" {
return "", fmt.Errorf("cel.paramKind.apiVersion is required")
if v.validationRule.CEL.ParamKind != nil {
if v.validationRule.CEL.ParamKind.APIVersion == "" {
return nil, "", fmt.Errorf("cel.paramKind.apiVersion is required")
}
if v.rule.CEL.ParamKind.Kind == "" {
return "", fmt.Errorf("cel.paramKind.kind is required")
if v.validationRule.CEL.ParamKind.Kind == "" {
return nil, "", fmt.Errorf("cel.paramKind.kind is required")
}
if v.rule.CEL.ParamRef == nil {
return "", fmt.Errorf("cel.paramRef is required")
if v.validationRule.CEL.ParamRef == nil {
return nil, "", fmt.Errorf("cel.paramRef is required")
}
}
if v.rule.CEL.ParamRef != nil {
if v.rule.CEL.ParamRef.Name == "" && v.rule.CEL.ParamRef.Selector == nil {
return "", fmt.Errorf("one of cel.paramRef.name or cel.paramRef.selector must be set")
if v.validationRule.CEL.ParamRef != nil {
if v.validationRule.CEL.ParamRef.Name == "" && v.validationRule.CEL.ParamRef.Selector == nil {
return nil, "", fmt.Errorf("one of cel.paramRef.name or cel.paramRef.selector must be set")
}
if v.rule.CEL.ParamRef.Name != "" && v.rule.CEL.ParamRef.Selector != nil {
return "", fmt.Errorf("one of cel.paramRef.name or cel.paramRef.selector must be set")
if v.validationRule.CEL.ParamRef.Name != "" && v.validationRule.CEL.ParamRef.Selector != nil {
return nil, "", fmt.Errorf("one of cel.paramRef.name or cel.paramRef.selector must be set")
}
if v.rule.CEL.ParamRef.ParameterNotFoundAction == nil {
return "", fmt.Errorf("cel.paramRef.parameterNotFoundAction is required")
if v.validationRule.CEL.ParamRef.ParameterNotFoundAction == nil {
return nil, "", fmt.Errorf("cel.paramRef.parameterNotFoundAction is required")
}
if v.rule.CEL.ParamKind == nil {
return "", fmt.Errorf("cel.paramKind is required")
if v.validationRule.CEL.ParamKind == nil {
return nil, "", fmt.Errorf("cel.paramKind is required")
}
}
if v.rule.CEL.AuditAnnotations != nil {
for _, auditAnnotation := range v.rule.CEL.AuditAnnotations {
if v.validationRule.CEL.AuditAnnotations != nil {
for _, auditAnnotation := range v.validationRule.CEL.AuditAnnotations {
if auditAnnotation.Key == "" {
return "", fmt.Errorf("cel.auditAnnotation.key is required")
return nil, "", fmt.Errorf("cel.auditAnnotation.key is required")
}
if auditAnnotation.ValueExpression == "" {
return "", fmt.Errorf("cel.auditAnnotation.valueExpression is required")
return nil, "", fmt.Errorf("cel.auditAnnotation.valueExpression is required")
}
}
}
}
return "", nil
if w, err := v.validateAuth(ctx); err != nil {
return nil, "", err
} else if len(w) > 0 {
warnings = append(warnings, w...)
}
return warnings, "", nil
}
func (v *Validate) validateAuth(ctx context.Context) (warnings []string, err error) {
kinds := v.rule.MatchResources.GetKinds()
for _, k := range kinds {
if wildcard.ContainsWildcard(k) {
return nil, nil
}
verbs := []string{"get", "list", "watch"}
ok, msg, err := v.authChecker.CanI(ctx, verbs, k, "", "", "")
if err != nil {
return nil, err
}
if !ok {
return []string{msg}, nil
}
}
return nil, nil
}
func (v *Validate) validateElements() error {
count := validationElemCount(v.rule)
count := validationElemCount(v.validationRule)
if count == 0 {
return fmt.Errorf("one of pattern, anyPattern, deny, foreach, cel must be specified")
}

View file

@ -13,12 +13,12 @@ func Test_Validate_OverlayPattern_Empty(t *testing.T) {
rawValidation := []byte(`
{}`)
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
var rule kyverno.Rule
err := json.Unmarshal(rawValidation, &rule)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&rule)
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -31,8 +31,8 @@ func Test_Validate_OverlayPattern_Nil_PatternAnypattern(t *testing.T) {
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -69,8 +69,8 @@ func Test_Validate_OverlayPattern_Exist_PatternAnypattern(t *testing.T) {
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -107,8 +107,8 @@ func Test_Validate_OverlayPattern_Valid(t *testing.T) {
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.NilError(t, err)
}
}
@ -140,8 +140,8 @@ func Test_Validate_ExistingAnchor_AnchorOnMap(t *testing.T) {
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -170,8 +170,8 @@ func Test_Validate_ExistingAnchor_AnchorOnString(t *testing.T) {
var validation kyverno.Validation
err := json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -203,8 +203,8 @@ func Test_Validate_ExistingAnchor_Valid(t *testing.T) {
err = json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker := NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
rawValidation = []byte(`
@ -228,8 +228,8 @@ func Test_Validate_ExistingAnchor_Valid(t *testing.T) {
} `)
err = json.Unmarshal(rawValidation, &validation)
assert.NilError(t, err)
checker = NewValidateFactory(&validation)
if _, err := checker.Validate(context.TODO()); err != nil {
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validation})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
@ -269,8 +269,8 @@ func Test_Validate_Validate_ValidAnchor(t *testing.T) {
err = json.Unmarshal(rawValidate, &validate)
assert.NilError(t, err)
checker := NewValidateFactory(&validate)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.NilError(t, err)
}
@ -291,8 +291,8 @@ func Test_Validate_Validate_ValidAnchor(t *testing.T) {
err = json.Unmarshal(rawValidate, &validate)
assert.NilError(t, err)
checker = NewValidateFactory(&validate)
if _, err := checker.Validate(context.TODO()); err != nil {
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validate})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.NilError(t, err)
}
}
@ -318,8 +318,8 @@ func Test_Validate_Validate_Mismatched(t *testing.T) {
var validate kyverno.Validation
err := json.Unmarshal(rawValidate, &validate)
assert.NilError(t, err)
checker := NewValidateFactory(&validate)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
}
@ -348,8 +348,8 @@ func Test_Validate_Validate_Unsupported(t *testing.T) {
err = json.Unmarshal(rawValidate, &validate)
assert.NilError(t, err)
checker := NewValidateFactory(&validate)
if _, err := checker.Validate(context.TODO()); err != nil {
checker := NewMockValidateFactory(&kyverno.Rule{Validation: validate})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}
@ -374,8 +374,8 @@ func Test_Validate_Validate_Unsupported(t *testing.T) {
err = json.Unmarshal(rawValidate, &validate)
assert.NilError(t, err)
checker = NewValidateFactory(&validate)
if _, err := checker.Validate(context.TODO()); err != nil {
checker = NewMockValidateFactory(&kyverno.Rule{Validation: validate})
if _, _, err := checker.Validate(context.TODO()); err != nil {
assert.Assert(t, err != nil)
}

View file

@ -73,18 +73,15 @@ func validateAuth(ctx context.Context, client dclient.Interface, policy kyvernov
resourceFilters := spec.MatchResources.GetResourceFilters()
for _, res := range resourceFilters {
for _, kind := range res.Kinds {
if len(res.Names) == 0 {
err := canI(ctx, client, kind, namespace, "", "")
names := res.Names
if len(names) == 0 {
names = append(names, "")
}
for _, name := range names {
err := canI(ctx, client, kind, namespace, name, "")
if err != nil {
return err
}
} else {
for _, name := range res.Names {
err := canI(ctx, client, kind, namespace, name, "")
if err != nil {
return err
}
}
}
}
}

View file

@ -9,8 +9,6 @@ import (
authChecker "github.com/kyverno/kyverno/pkg/auth/checker"
"github.com/kyverno/kyverno/pkg/clients/dclient"
"github.com/kyverno/kyverno/pkg/logging"
"github.com/kyverno/kyverno/pkg/policy/auth"
"github.com/kyverno/kyverno/pkg/policy/auth/fake"
"github.com/kyverno/kyverno/pkg/policy/generate"
"github.com/kyverno/kyverno/pkg/policy/mutate"
"github.com/kyverno/kyverno/pkg/policy/validate"
@ -20,51 +18,47 @@ import (
// Validation provides methods to validate a rule
type Validation interface {
Validate(ctx context.Context) (string, error)
Validate(ctx context.Context) (warnings []string, path string, err error)
}
// validateAction performs validation on the rule actions
// - Mutate
// - Validation
// - Generate
func validateActions(idx int, rule *kyvernov1.Rule, client dclient.Interface, mock bool, username string) (string, error) {
func validateActions(idx int, rule *kyvernov1.Rule, client dclient.Interface, mock bool, backgroundSA, reportsSA string) (warnings []string, err error) {
if rule == nil {
return "", nil
return nil, nil
}
var checker Validation
// Mutate
if rule.HasMutate() {
var authChecker auth.Operations
if mock {
authChecker = fake.NewFakeAuth()
} else {
authChecker = auth.NewAuth(client, username, logging.GlobalLogger())
}
checker = mutate.NewMutateFactory(rule.Mutation, authChecker, username)
if path, err := checker.Validate(context.TODO()); err != nil {
return "", fmt.Errorf("path: spec.rules[%d].mutate.%s.: %v", idx, path, err)
checker = mutate.NewMutateFactory(rule.Mutation, client, mock, backgroundSA)
if w, path, err := checker.Validate(context.TODO()); err != nil {
return nil, fmt.Errorf("path: spec.rules[%d].mutate.%s.: %v", idx, path, err)
} else if w != nil {
warnings = append(warnings, w...)
}
}
// Validate
if rule.HasValidate() {
checker = validate.NewValidateFactory(&rule.Validation)
if path, err := checker.Validate(context.TODO()); err != nil {
return "", fmt.Errorf("path: spec.rules[%d].validate.%s.: %v", idx, path, err)
checker = validate.NewValidateFactory(rule, client, mock, reportsSA)
if w, path, err := checker.Validate(context.TODO()); err != nil {
return nil, fmt.Errorf("path: spec.rules[%d].validate.%s.: %v", idx, path, err)
} else if w != nil {
warnings = append(warnings, w...)
}
// In case generateValidatingAdmissionPolicy flag is set to true, check the required permissions.
if rule.HasValidateCEL() && toggle.FromContext(context.TODO()).GenerateValidatingAdmissionPolicy() {
authCheck := authChecker.NewSelfChecker(client.GetKubeClient().AuthorizationV1().SelfSubjectAccessReviews())
// check if the controller has the required permissions to generate validating admission policies.
if !validatingadmissionpolicy.HasValidatingAdmissionPolicyPermission(authCheck) {
return "insufficient permissions to generate ValidatingAdmissionPolicies", nil
warnings = append(warnings, "insufficient permissions to generate ValidatingAdmissionPolicies")
}
// check if the controller has the required permissions to generate validating admission policy bindings.
if !validatingadmissionpolicy.HasValidatingAdmissionPolicyBindingPermission(authCheck) {
return "insufficient permissions to generate ValidatingAdmissionPolicyBindings", nil
warnings = append(warnings, "insufficient permissions to generate ValidatingAdmissionPolicies")
}
}
}
@ -76,20 +70,24 @@ func validateActions(idx int, rule *kyvernov1.Rule, client dclient.Interface, mo
// this need to modified to use different implementation for online and offline mode
if mock {
checker = generate.NewFakeGenerate(rule.Generation)
if path, err := checker.Validate(context.TODO()); err != nil {
return "", fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
if w, path, err := checker.Validate(context.TODO()); err != nil {
return nil, fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
} else if warnings != nil {
warnings = append(warnings, w...)
}
} else {
checker = generate.NewGenerateFactory(client, rule.Generation, username, logging.GlobalLogger())
if path, err := checker.Validate(context.TODO()); err != nil {
return "", fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
checker = generate.NewGenerateFactory(client, rule.Generation, backgroundSA, logging.GlobalLogger())
if w, path, err := checker.Validate(context.TODO()); err != nil {
return nil, fmt.Errorf("path: spec.rules[%d].generate.%s.: %v", idx, path, err)
} else if warnings != nil {
warnings = append(warnings, w...)
}
}
if slices.Contains(rule.MatchResources.Kinds, rule.Generation.Kind) {
return "", fmt.Errorf("generation kind and match resource kind should not be the same")
return nil, fmt.Errorf("generation kind and match resource kind should not be the same")
}
}
return "", nil
return warnings, nil
}

View file

@ -14,6 +14,6 @@ func FuzzValidatePolicy(f *testing.F) {
p := &kyverno.ClusterPolicy{}
ff.GenerateStruct(p)
Validate(p, nil, nil, nil, true, "admin")
Validate(p, nil, nil, nil, true, "admin", "admin")
})
}

View file

@ -128,7 +128,7 @@ func checkValidationFailureAction(validationFailureAction kyvernov1.ValidationFa
}
// Validate checks the policy and rules declarations for required configurations
func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interface, kyvernoClient versioned.Interface, mock bool, username string) ([]string, error) {
func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interface, kyvernoClient versioned.Interface, mock bool, backgroundSA, reportsSA string) ([]string, error) {
var warnings []string
spec := policy.GetSpec()
background := spec.BackgroundProcessingEnabled()
@ -322,13 +322,11 @@ func Validate(policy, oldPolicy kyvernov1.PolicyInterface, client dclient.Interf
}
}
msg, err := validateActions(i, &rules[i], client, mock, username)
w, err := validateActions(i, &rules[i], client, mock, backgroundSA, reportsSA)
if err != nil {
return warnings, err
} else {
if len(msg) != 0 {
warnings = append(warnings, msg)
}
} else if len(w) > 0 {
warnings = append(warnings, w...)
}
if rule.HasVerifyImages() {

View file

@ -17,13 +17,15 @@ type policyHandlers struct {
client dclient.Interface
kyvernoClient versioned.Interface
backgroundServiceAccountName string
reportsServiceAccountName string
}
func NewHandlers(client dclient.Interface, kyvernoClient versioned.Interface, serviceaccount string) webhooks.PolicyHandlers {
func NewHandlers(client dclient.Interface, kyvernoClient versioned.Interface, backgroundSA, reportsSA string) webhooks.PolicyHandlers {
return &policyHandlers{
client: client,
kyvernoClient: kyvernoClient,
backgroundServiceAccountName: serviceaccount,
backgroundServiceAccountName: backgroundSA,
reportsServiceAccountName: reportsSA,
}
}
@ -33,7 +35,7 @@ func (h *policyHandlers) Validate(ctx context.Context, logger logr.Logger, reque
logger.Error(err, "failed to unmarshal policies from admission request")
return admissionutils.Response(request.UID, err)
}
warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, h.kyvernoClient, false, h.backgroundServiceAccountName)
warnings, err := policyvalidate.Validate(policy, oldPolicy, h.client, h.kyvernoClient, false, h.backgroundServiceAccountName, h.reportsServiceAccountName)
if err != nil {
logger.Error(err, "policy validation errors")
}

View file

@ -43,6 +43,7 @@ func NewGenerationHandler(
eventGen event.Interface,
metrics metrics.MetricsConfigManager,
backgroundServiceAccountName string,
reportsServiceAccountName string,
) GenerationHandler {
return &generationHandler{
log: log,
@ -57,6 +58,7 @@ func NewGenerationHandler(
eventGen: eventGen,
metrics: metrics,
backgroundServiceAccountName: backgroundServiceAccountName,
reportsServiceAccountName: reportsServiceAccountName,
}
}
@ -73,6 +75,7 @@ type generationHandler struct {
eventGen event.Interface
metrics metrics.MetricsConfigManager
backgroundServiceAccountName string
reportsServiceAccountName string
}
func (h *generationHandler) Handle(

View file

@ -63,6 +63,7 @@ type resourceHandlers struct {
admissionReports bool
backgroundServiceAccountName string
reportsServiceAccountName string
auditPool *pond.WorkerPool
reportsBreaker breaker.Breaker
}
@ -82,6 +83,7 @@ func NewHandlers(
eventGen event.Interface,
admissionReports bool,
backgroundServiceAccountName string,
reportsServiceAccountName string,
jp jmespath.Interface,
maxAuditWorkers int,
maxAuditCapacity int,
@ -103,6 +105,7 @@ func NewHandlers(
pcBuilder: webhookutils.NewPolicyContextBuilder(configuration, jp),
admissionReports: admissionReports,
backgroundServiceAccountName: backgroundServiceAccountName,
reportsServiceAccountName: reportsServiceAccountName,
auditPool: pond.New(maxAuditWorkers, maxAuditCapacity, pond.Strategy(pond.Lazy())),
reportsBreaker: reportsBreaker,
}

View file

@ -106,7 +106,7 @@ func (h *resourceHandlers) handleGenerate(ctx context.Context, logger logr.Logge
return
}
gh := generation.NewGenerationHandler(logger, h.engine, h.client, h.kyvernoClient, h.nsLister, h.urLister, h.cpolLister, h.polLister, h.urGenerator, h.eventGen, h.metricsConfig, h.backgroundServiceAccountName)
gh := generation.NewGenerationHandler(logger, h.engine, h.client, h.kyvernoClient, h.nsLister, h.urLister, h.cpolLister, h.polLister, h.urGenerator, h.eventGen, h.metricsConfig, h.backgroundServiceAccountName, h.reportsServiceAccountName)
var policies []kyvernov1.PolicyInterface
for _, p := range generatePolicies {
new := skipBackgroundRequests(p, logger, h.backgroundServiceAccountName, policyContext.AdmissionInfo().AdmissionUserInfo.Username)

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-091a1b
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-819b1b
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,18 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:role-and-rolebinding
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
- rolebindings
verbs:
- get
- list
- watch

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-19hs91
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-la91n1
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-1pq1b
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-91ys8
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-k8312
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-kao19a
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-kaa11
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,33 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:view
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:generate
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-018m1
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-10ga3
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-1kq1a
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-mabt11
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-nqu34
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-l1k10
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,33 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-view-91ja1
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:edit-1k1o2
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-a12xk
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -10,6 +10,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: roles.yaml
- name: step-02

View file

@ -0,0 +1,19 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:rbac
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
- clusterrolebindings
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- assert:

View file

@ -0,0 +1,19 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:rbac
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
- rolebindings
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -12,4 +12,38 @@ rules:
resources:
- deployments
verbs:
- update
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-jqo11
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:manage-1lh1k
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- update
- delete

View file

@ -12,4 +12,38 @@ rules:
resources:
- deployments
verbs:
- update
- update
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-kak13
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets:manage-ja51n
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: manifests.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-lal13
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-kqo1
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-k113f
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -13,6 +13,8 @@ spec:
file: policy-ready.yaml
- name: step-02
try:
- apply:
file: permissions.yaml
- apply:
file: ns.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-skh1
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-0191s
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-la1lk
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-ka32a
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-oa11s
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: policy.yaml
- assert:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-nsalj
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-lkjso
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: manifests.yaml
- apply:

View file

@ -0,0 +1,20 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: kyverno:secrets-xaeqi
labels:
rbac.kyverno.io/aggregate-to-background-controller: "true"
rbac.kyverno.io/aggregate-to-reports-controller: "true"
rbac.kyverno.io/aggregate-to-admission-controller: "true"
rules:
- apiGroups:
- ''
resources:
- secrets
verbs:
- get
- list
- watch
- create
- update
- delete

View file

@ -7,6 +7,8 @@ spec:
steps:
- name: step-01
try:
- apply:
file: permissions.yaml
- apply:
file: chainsaw-step-01-apply-1-1.yaml
- apply:

Some files were not shown because too many files have changed in this diff Show more