...

Source file src/k8s.io/kubernetes/pkg/registry/admissionregistration/validatingadmissionpolicybinding/authz.go

Documentation: k8s.io/kubernetes/pkg/registry/admissionregistration/validatingadmissionpolicybinding

     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  }
   118  

View as plain text