Skip to content

Commit ba2eecc

Browse files
committed
Add TokenAttributes field to v1 CredentialProvider
Signed-off-by: Anish Ramasekar <[email protected]>
1 parent c5d4e53 commit ba2eecc

File tree

11 files changed

+423
-25
lines changed

11 files changed

+423
-25
lines changed

pkg/generated/openapi/zz_generated.openapi.go

Lines changed: 77 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/kubelet/apis/config/fuzzer/fuzzer.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,5 +127,11 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} {
127127
"AllBeta": true,
128128
}
129129
},
130+
131+
// tokenAttributes field is only supported in v1 CredentialProvider
132+
func(obj *kubeletconfig.CredentialProvider, c randfill.Continue) {
133+
c.FillNoCustom(obj)
134+
obj.TokenAttributes = nil
135+
},
130136
}
131137
}

pkg/kubelet/apis/config/types.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -670,6 +670,64 @@ type CredentialProvider struct {
670670
// to pass argument to the plugin.
671671
// +optional
672672
Env []ExecEnvVar
673+
674+
// tokenAttributes is the configuration for the service account token that will be passed to the plugin.
675+
// The credential provider opts in to using service account tokens for image pull by setting this field.
676+
// When this field is set, kubelet will generate a service account token bound to the pod for which the
677+
// image is being pulled and pass to the plugin as part of CredentialProviderRequest along with other
678+
// attributes required by the plugin.
679+
//
680+
// The service account metadata and token attributes will be used as a dimension to cache
681+
// the credentials in kubelet. The cache key is generated by combining the service account metadata
682+
// (namespace, name, UID, and annotations key+value for the keys defined in
683+
// serviceAccountTokenAttribute.requiredServiceAccountAnnotationKeys and serviceAccountTokenAttribute.optionalServiceAccountAnnotationKeys).
684+
// The pod metadata (namespace, name, UID) that are in the service account token are not used as a dimension
685+
// to cache the credentials in kubelet. This means workloads that are using the same service account
686+
// could end up using the same credentials for image pull. For plugins that don't want this behavior, or
687+
// plugins that operate in pass-through mode; i.e., they return the service account token as-is, they
688+
// can set the credentialProviderResponse.cacheDuration to 0. This will disable the caching of
689+
// credentials in kubelet and the plugin will be invoked for every image pull. This does result in
690+
// token generation overhead for every image pull, but it is the only way to ensure that the
691+
// credentials are not shared across pods (even if they are using the same service account).
692+
// +optional
693+
TokenAttributes *ServiceAccountTokenAttributes
694+
}
695+
696+
// ServiceAccountTokenAttributes is the configuration for the service account token that will be passed to the plugin.
697+
type ServiceAccountTokenAttributes struct {
698+
// serviceAccountTokenAudience is the intended audience for the projected service account token.
699+
// +required
700+
ServiceAccountTokenAudience string
701+
702+
// requireServiceAccount indicates whether the plugin requires the pod to have a service account.
703+
// If set to true, kubelet will only invoke the plugin if the pod has a service account.
704+
// If set to false, kubelet will invoke the plugin even if the pod does not have a service account
705+
// and will not include a token in the CredentialProviderRequest in that scenario. This is useful for plugins that
706+
// are used to pull images for pods without service accounts (e.g., static pods).
707+
// +required
708+
RequireServiceAccount *bool
709+
710+
// requiredServiceAccountAnnotationKeys is the list of annotation keys that the plugin is interested in
711+
// and that are required to be present in the service account.
712+
// The keys defined in this list will be extracted from the corresponding service account and passed
713+
// to the plugin as part of the CredentialProviderRequest. If any of the keys defined in this list
714+
// are not present in the service account, kubelet will not invoke the plugin and will return an error.
715+
// This field is optional and may be empty. Plugins may use this field to extract
716+
// additional information required to fetch credentials or allow workloads to opt in to
717+
// using service account tokens for image pull.
718+
// If non-empty, requireServiceAccount must be set to true.
719+
// +optional
720+
RequiredServiceAccountAnnotationKeys []string
721+
722+
// optionalServiceAccountAnnotationKeys is the list of annotation keys that the plugin is interested in
723+
// and that are optional to be present in the service account.
724+
// The keys defined in this list will be extracted from the corresponding service account and passed
725+
// to the plugin as part of the CredentialProviderRequest. The plugin is responsible for validating
726+
// the existence of annotations and their values.
727+
// This field is optional and may be empty. Plugins may use this field to extract
728+
// additional information required to fetch credentials.
729+
// +optional
730+
OptionalServiceAccountAnnotationKeys []string
673731
}
674732

675733
// ExecEnvVar is used for setting environment variables when executing an exec-based

pkg/kubelet/apis/config/v1/zz_generated.conversion.go

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2025 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 v1alpha1
18+
19+
import (
20+
"k8s.io/apimachinery/pkg/conversion"
21+
configv1alpha1 "k8s.io/kubelet/config/v1alpha1"
22+
"k8s.io/kubernetes/pkg/kubelet/apis/config"
23+
)
24+
25+
func Convert_config_CredentialProvider_To_v1alpha1_CredentialProvider(in *config.CredentialProvider, out *configv1alpha1.CredentialProvider, s conversion.Scope) error {
26+
// This conversion intentionally omits the tokenAttributes field which is only supported in v1 CredentialProvider.
27+
return autoConvert_config_CredentialProvider_To_v1alpha1_CredentialProvider(in, out, s)
28+
}

0 commit comments

Comments
 (0)