k8s.io/kubernetes@v1.29.3/pkg/kubeapiserver/authorizer/config.go (about)

     1  /*
     2  Copyright 2016 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 authorizer
    18  
    19  import (
    20  	"errors"
    21  	"fmt"
    22  
    23  	utilnet "k8s.io/apimachinery/pkg/util/net"
    24  	"k8s.io/apimachinery/pkg/util/wait"
    25  	authzconfig "k8s.io/apiserver/pkg/apis/apiserver"
    26  	"k8s.io/apiserver/pkg/authentication/user"
    27  	"k8s.io/apiserver/pkg/authorization/authorizer"
    28  	"k8s.io/apiserver/pkg/authorization/authorizerfactory"
    29  	"k8s.io/apiserver/pkg/authorization/union"
    30  	webhookutil "k8s.io/apiserver/pkg/util/webhook"
    31  	"k8s.io/apiserver/plugin/pkg/authorizer/webhook"
    32  	versionedinformers "k8s.io/client-go/informers"
    33  	"k8s.io/kubernetes/pkg/auth/authorizer/abac"
    34  	"k8s.io/kubernetes/pkg/auth/nodeidentifier"
    35  	"k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes"
    36  	"k8s.io/kubernetes/plugin/pkg/auth/authorizer/node"
    37  	"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac"
    38  	"k8s.io/kubernetes/plugin/pkg/auth/authorizer/rbac/bootstrappolicy"
    39  )
    40  
    41  // Config contains the data on how to authorize a request to the Kube API Server
    42  type Config struct {
    43  	// Options for ModeABAC
    44  
    45  	// Path to an ABAC policy file.
    46  	PolicyFile string
    47  
    48  	// Options for ModeWebhook
    49  
    50  	// WebhookRetryBackoff specifies the backoff parameters for the authorization webhook retry logic.
    51  	// This allows us to configure the sleep time at each iteration and the maximum number of retries allowed
    52  	// before we fail the webhook call in order to limit the fan out that ensues when the system is degraded.
    53  	WebhookRetryBackoff *wait.Backoff
    54  
    55  	VersionedInformerFactory versionedinformers.SharedInformerFactory
    56  
    57  	// Optional field, custom dial function used to connect to webhook
    58  	CustomDial utilnet.DialFunc
    59  
    60  	// AuthorizationConfiguration stores the configuration for the Authorizer chain
    61  	// It will deprecate most of the above flags when GA
    62  	AuthorizationConfiguration *authzconfig.AuthorizationConfiguration
    63  }
    64  
    65  // New returns the right sort of union of multiple authorizer.Authorizer objects
    66  // based on the authorizationMode or an error.
    67  func (config Config) New() (authorizer.Authorizer, authorizer.RuleResolver, error) {
    68  	if len(config.AuthorizationConfiguration.Authorizers) == 0 {
    69  		return nil, nil, fmt.Errorf("at least one authorization mode must be passed")
    70  	}
    71  
    72  	var (
    73  		authorizers   []authorizer.Authorizer
    74  		ruleResolvers []authorizer.RuleResolver
    75  	)
    76  
    77  	// Add SystemPrivilegedGroup as an authorizing group
    78  	superuserAuthorizer := authorizerfactory.NewPrivilegedGroups(user.SystemPrivilegedGroup)
    79  	authorizers = append(authorizers, superuserAuthorizer)
    80  
    81  	for _, configuredAuthorizer := range config.AuthorizationConfiguration.Authorizers {
    82  		// Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go.
    83  		switch configuredAuthorizer.Type {
    84  		case authzconfig.AuthorizerType(modes.ModeNode):
    85  			node.RegisterMetrics()
    86  			graph := node.NewGraph()
    87  			node.AddGraphEventHandlers(
    88  				graph,
    89  				config.VersionedInformerFactory.Core().V1().Nodes(),
    90  				config.VersionedInformerFactory.Core().V1().Pods(),
    91  				config.VersionedInformerFactory.Core().V1().PersistentVolumes(),
    92  				config.VersionedInformerFactory.Storage().V1().VolumeAttachments(),
    93  			)
    94  			nodeAuthorizer := node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
    95  			authorizers = append(authorizers, nodeAuthorizer)
    96  			ruleResolvers = append(ruleResolvers, nodeAuthorizer)
    97  
    98  		case authzconfig.AuthorizerType(modes.ModeAlwaysAllow):
    99  			alwaysAllowAuthorizer := authorizerfactory.NewAlwaysAllowAuthorizer()
   100  			authorizers = append(authorizers, alwaysAllowAuthorizer)
   101  			ruleResolvers = append(ruleResolvers, alwaysAllowAuthorizer)
   102  		case authzconfig.AuthorizerType(modes.ModeAlwaysDeny):
   103  			alwaysDenyAuthorizer := authorizerfactory.NewAlwaysDenyAuthorizer()
   104  			authorizers = append(authorizers, alwaysDenyAuthorizer)
   105  			ruleResolvers = append(ruleResolvers, alwaysDenyAuthorizer)
   106  		case authzconfig.AuthorizerType(modes.ModeABAC):
   107  			abacAuthorizer, err := abac.NewFromFile(config.PolicyFile)
   108  			if err != nil {
   109  				return nil, nil, err
   110  			}
   111  			authorizers = append(authorizers, abacAuthorizer)
   112  			ruleResolvers = append(ruleResolvers, abacAuthorizer)
   113  		case authzconfig.AuthorizerType(modes.ModeWebhook):
   114  			if config.WebhookRetryBackoff == nil {
   115  				return nil, nil, errors.New("retry backoff parameters for authorization webhook has not been specified")
   116  			}
   117  			clientConfig, err := webhookutil.LoadKubeconfig(*configuredAuthorizer.Webhook.ConnectionInfo.KubeConfigFile, config.CustomDial)
   118  			if err != nil {
   119  				return nil, nil, err
   120  			}
   121  			var decisionOnError authorizer.Decision
   122  			switch configuredAuthorizer.Webhook.FailurePolicy {
   123  			case authzconfig.FailurePolicyNoOpinion:
   124  				decisionOnError = authorizer.DecisionNoOpinion
   125  			case authzconfig.FailurePolicyDeny:
   126  				decisionOnError = authorizer.DecisionDeny
   127  			default:
   128  				return nil, nil, fmt.Errorf("unknown failurePolicy %q", configuredAuthorizer.Webhook.FailurePolicy)
   129  			}
   130  			webhookAuthorizer, err := webhook.New(clientConfig,
   131  				configuredAuthorizer.Webhook.SubjectAccessReviewVersion,
   132  				configuredAuthorizer.Webhook.AuthorizedTTL.Duration,
   133  				configuredAuthorizer.Webhook.UnauthorizedTTL.Duration,
   134  				*config.WebhookRetryBackoff,
   135  				decisionOnError,
   136  				configuredAuthorizer.Webhook.MatchConditions,
   137  			)
   138  			if err != nil {
   139  				return nil, nil, err
   140  			}
   141  			authorizers = append(authorizers, webhookAuthorizer)
   142  			ruleResolvers = append(ruleResolvers, webhookAuthorizer)
   143  		case authzconfig.AuthorizerType(modes.ModeRBAC):
   144  			rbacAuthorizer := rbac.New(
   145  				&rbac.RoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().Roles().Lister()},
   146  				&rbac.RoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().RoleBindings().Lister()},
   147  				&rbac.ClusterRoleGetter{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoles().Lister()},
   148  				&rbac.ClusterRoleBindingLister{Lister: config.VersionedInformerFactory.Rbac().V1().ClusterRoleBindings().Lister()},
   149  			)
   150  			authorizers = append(authorizers, rbacAuthorizer)
   151  			ruleResolvers = append(ruleResolvers, rbacAuthorizer)
   152  		default:
   153  			return nil, nil, fmt.Errorf("unknown authorization mode %s specified", configuredAuthorizer.Type)
   154  		}
   155  	}
   156  
   157  	return union.New(authorizers...), union.NewRuleResolvers(ruleResolvers...), nil
   158  }