k8s.io/kubernetes@v1.29.3/pkg/registry/admissionregistration/validatingadmissionpolicybinding/authz.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package validatingadmissionpolicybinding 18 19 import ( 20 "context" 21 "fmt" 22 23 "k8s.io/apimachinery/pkg/runtime" 24 "k8s.io/apimachinery/pkg/runtime/schema" 25 "k8s.io/apiserver/pkg/authorization/authorizer" 26 genericapirequest "k8s.io/apiserver/pkg/endpoints/request" 27 "k8s.io/kubernetes/pkg/apis/admissionregistration" 28 rbacregistry "k8s.io/kubernetes/pkg/registry/rbac" 29 ) 30 31 func (v *validatingAdmissionPolicyBindingStrategy) authorizeCreate(ctx context.Context, obj runtime.Object) error { 32 binding := obj.(*admissionregistration.ValidatingAdmissionPolicyBinding) 33 if binding.Spec.ParamRef == nil { 34 // no paramRef in new object 35 return nil 36 } 37 38 return v.authorize(ctx, binding) 39 } 40 41 func (v *validatingAdmissionPolicyBindingStrategy) authorizeUpdate(ctx context.Context, obj, old runtime.Object) error { 42 binding := obj.(*admissionregistration.ValidatingAdmissionPolicyBinding) 43 if binding.Spec.ParamRef == nil { 44 // no paramRef in new object 45 return nil 46 } 47 48 oldBinding := old.(*admissionregistration.ValidatingAdmissionPolicyBinding) 49 if oldBinding.Spec.ParamRef != nil && *oldBinding.Spec.ParamRef == *binding.Spec.ParamRef && oldBinding.Spec.PolicyName == binding.Spec.PolicyName { 50 // identical paramRef and policy to old object 51 return nil 52 } 53 54 return v.authorize(ctx, binding) 55 } 56 57 func (v *validatingAdmissionPolicyBindingStrategy) authorize(ctx context.Context, binding *admissionregistration.ValidatingAdmissionPolicyBinding) error { 58 if v.authorizer == nil || v.resourceResolver == nil || binding.Spec.ParamRef == nil { 59 return nil 60 } 61 62 // for superuser, skip all checks 63 if rbacregistry.EscalationAllowed(ctx) { 64 return nil 65 } 66 67 user, ok := genericapirequest.UserFrom(ctx) 68 if !ok { 69 return fmt.Errorf("cannot identify user to authorize read access to paramRef object") 70 } 71 72 // default to requiring permissions on all group/version/resources 73 resource, apiGroup, apiVersion := "*", "*", "*" 74 75 if policy, err := v.policyGetter.GetValidatingAdmissionPolicy(ctx, binding.Spec.PolicyName); err == nil && policy.Spec.ParamKind != nil { 76 paramKind := policy.Spec.ParamKind 77 if gv, err := schema.ParseGroupVersion(paramKind.APIVersion); err == nil { 78 // we only need to authorize the parsed group/version 79 apiGroup = gv.Group 80 apiVersion = gv.Version 81 if gvr, err := v.resourceResolver.Resolve(gv.WithKind(paramKind.Kind)); err == nil { 82 // we only need to authorize the resolved resource 83 resource = gvr.Resource 84 } 85 } 86 } 87 88 var attrs authorizer.AttributesRecord 89 90 paramRef := binding.Spec.ParamRef 91 verb := "get" 92 93 if len(paramRef.Name) == 0 { 94 verb = "list" 95 } 96 97 attrs = authorizer.AttributesRecord{ 98 User: user, 99 Verb: verb, 100 ResourceRequest: true, 101 Name: paramRef.Name, 102 Namespace: paramRef.Namespace, // if empty, no namespace indicates get across all namespaces 103 APIGroup: apiGroup, 104 APIVersion: apiVersion, 105 Resource: resource, 106 } 107 108 d, _, err := v.authorizer.Authorize(ctx, attrs) 109 if err != nil { 110 return err 111 } 112 if d != authorizer.DecisionAllow { 113 return fmt.Errorf(`user %v does not have "%v" permission on the object referenced by paramRef`, verb, user) 114 } 115 116 return nil 117 }