diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer.go b/plugin/pkg/auth/authorizer/node/node_authorizer.go index aac48afb026..59fd9836c6f 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer.go @@ -368,7 +368,18 @@ func (r *NodeAuthorizer) authorizeNode(nodeName string, attrs authorizer.Attribu // Use the NodeRestriction admission plugin to limit a node to creating/updating its own API object. return authorizer.DecisionAllow, "", nil case "get", "list", "watch": - return r.authorize(nodeName, nodeVertexType, attrs) + // Compare the name directly, rather than using the graph, + // so kubelets can attempt a read of their Node API object prior to creation. + switch attrs.GetName() { + case nodeName: + return authorizer.DecisionAllow, "", nil + case "": + klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) + return authorizer.DecisionNoOpinion, fmt.Sprintf("node '%s' cannot read all nodes, only its own Node object", nodeName), nil + default: + klog.V(2).Infof("NODE DENY: '%s' %#v", nodeName, attrs) + return authorizer.DecisionNoOpinion, fmt.Sprintf("node '%s' cannot read '%s', only its own Node object", nodeName, attrs.GetName()), nil + } } case "status": switch attrs.GetVerb() { diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index 1f61b6ebd38..4edef661990 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -70,6 +70,8 @@ func TestNodeAuthorizer(t *testing.T) { node0 := &user.DefaultInfo{Name: "system:node:node0", Groups: []string{"system:nodes"}} + nodeunregistered := &user.DefaultInfo{Name: "system:node:nodeunregistered", Groups: []string{"system:nodes"}} + selectorAuthzDisabled := utilfeature.DefaultFeatureGate.DeepCopy() featuregatetesting.SetFeatureGateDuringTest(t, selectorAuthzDisabled, genericfeatures.AuthorizeWithSelectors, false) featuregatetesting.SetFeatureGateDuringTest(t, selectorAuthzDisabled, features.AuthorizeNodeWithSelectors, false) @@ -585,6 +587,11 @@ func TestNodeAuthorizer(t *testing.T) { // nodes // get nodes + { + name: "get related unregistered node", + attrs: authorizer.AttributesRecord{User: nodeunregistered, ResourceRequest: true, Verb: "get", Resource: "nodes", APIGroup: "", Name: "nodeunregistered"}, + expect: authorizer.DecisionAllow, + }, { name: "get related node", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "nodes", APIGroup: "", Name: "node0"},