Skip to content

Commit 792f846

Browse files
michaelawyumichaelawyu
authored andcommitted
Minor changes to KEP 5339
Signed-off-by: michaelawyu <chenyu1@microsoft.com>
1 parent 6b49ddf commit 792f846

File tree

1 file changed

+82
-5
lines changed
  • keps/sig-multicluster/5339-clusterprofile-plugin-credentials

1 file changed

+82
-5
lines changed

keps/sig-multicluster/5339-clusterprofile-plugin-credentials/README.md

Lines changed: 82 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,8 @@ controller, applications or consumers without requiring changes. It also cannot
224224
is not sensitive.
225225

226226
The definition is as follows:
227-
```
227+
228+
```golang
228229
type CredentialProviders struct {
229230
// +listType=map
230231
// +listMapKey=name
@@ -234,10 +235,17 @@ type CredentialProviders struct {
234235
// CredentialsTypes defines the type of credentials that are accepted by the cluster. For example, GCP credentials (tokens that are understood by GCP's IAM) are designated by the string `google`.
235236
type CredentialsType string
236237

238+
// AdditionalInformation is a piece of additional information with a nickname.
239+
type AdditionalInformation struct {
240+
Name string
241+
Data runtime.RawExtension
242+
}
243+
237244
// CredentialsConfig gives more details on data that is necessary to reach out the cluster for this kind of Credentials
238245
type CredentialsConfig struct {
239246
Name string // name of the provider type
240-
Cluster *Cluster // Configuration to reach the cluster (endpoints, proxy, etc) // See following section for details.
247+
Cluster *Cluster // Configuration to reach the cluster (endpoints, proxy, etc) // See the sections below for details.
248+
AdditionalInfo []AdditionalInformation // AdditionalInfo holds additional information that might be of use to the credential provider. See the sections below for details.
241249
}
242250
```
243251

@@ -290,6 +298,75 @@ In this structure, not all fields would apply, such as:
290298

291299
* `CertificateAuthority`, which points to a file (and a ClusterProfile doesn't have a filesystem)
292300

301+
##### About the `Extensions` field
302+
303+
The `Cluster` struct defined in `client-go` ([link](https://github.com/kubernetes/client-go/blob/d32752779319f587c42ff9edbc6ed533575f2136/tools/clientcmd/api/types.go#L69))
304+
features a field, `extensions`, for holding additional information about the cluster, with each extension associated with a name.
305+
[KEP-541](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/541-external-credential-providers/README.md) further reserves a name,
306+
`client.authentication.k8s.io/exec`, for per-cluster additional information for authentication exec plugins.
307+
Per KEP-541's explanation, if the `client.authentication.k8s.io/exec` extension has been set in the `Cluster` struct, the data shall be
308+
parsed and populated into the `Config` field of the `ExecConfig` struct (also defined in the `client-go` package, see [link](https://github.com/kubernetes/client-go/blob/d32752779319f587c42ff9edbc6ed533575f2136/tools/clientcmd/api/types.go#L209)).
309+
If the `ExecConfig` struct has its `ProvideClusterInfo` flag set to true, the `client-go` package, upon invocation of an exec plugin, will build a
310+
`Cluster` object (from the `client.authentication.k8s.io` API group, see [link](https://pkg.go.dev/k8s.io/client-go/pkg/apis/clientauthentication#Cluster)),
311+
which includes the parsed extension data (`Config` field in the `ExecConfig` struct), and save it to an environment variable, `KUBERNETES_EXEC_INFO`.
312+
313+
For workflow defined in this KEP, however, as described earlier in this document, it is up to the community-provided library to build a
314+
`rest.Config` and return it to the caller based on some user-supplied exec plugin information, which already features an `ExecConfig` struct
315+
(with the path to the exec plugin, arguments, environment variables, etc.) before it reads a `ClusterProfile` object; if the `ClusterProfile` object
316+
has extensions set, it might be of conflict with the `ExecConfig.Config` field that the community libraries sees (typically, as KEP-541 dictates, data
317+
in `ExecConfig.Config` should be sourced from `Cluster.Extensions`). Aside from the conflicts, there are other complications as well:
318+
319+
* without proper hints, it would not be clear how the data from the `client.authentication.k8s.io/exec` extension entry should be parsed; to use the data,
320+
the credential provider code must know a concrete object type that implements `runtime.Object` so that it could deserialize the data, in the form of
321+
`runtime.RawExtension`, to the object type; or choose to use `runtime.Unknown` as the object type (with its type meta information possibly missing).
322+
* whether the data from the `extensions` field can be seen by the exec plugin is ultimately decided by the `ProvideClusterInfo` flag in the `ExecConfig`, which
323+
is solely controlled by the credential provider code. If the flag is unset, any extension set on the cluster profile object will not used at all. Note also
324+
that the default value for `ProvideClusterInfo` is set to false.
325+
* there are also cases where setting the `ProvideClusterInfo` flag to true is not desirable or practicable, as it might involve writing a very large piece of CA data
326+
as an environment variable.
327+
* there are exec plugins that do not read the `KUBERNETES_EXEC_INFO` environment variable, or only read partial data from it (e.g., API versions only).
328+
329+
For the reasons explicated above, it is suggested that, when setting the `Cluster` struct in a `ClusterProfile` object, the `extensions` field should be handled
330+
by the community-provided credential provider library as follows:
331+
332+
* If the user-supplied `ExecConfig` struct has a non-nil `Config` field, or the `ProvideClusterInfo` flag is set to false, the library shall ignore
333+
any `extensions` data set in `ClusterProfile` objects;
334+
* Otherwise, the library checks for the reserved name, `client.authentication.k8s.io/exec`, in the `extensions` field from the `ClusterProfile` object
335+
in use, and source the `ExecConfig.Config` field accordingly by saving the the `extensions` data as a `runtime.Unknown` object.
336+
337+
Considering the complications with the usage of `extensions` field in a multi-cluster environment for authentication, users might need a more direct way
338+
to provide cluster-specific information to the exec plugin to complete the authentication workflow; the information might include client IDs,
339+
tenant IDs, and/or audiences. Such information is very difficult to handle on the controller side as it either requires engineers to hard-code
340+
the values for each cluster, or implement some form dynamic discovery mechanism. To facilitate such use cases, this KEP adds an `AdditionalInfo` field
341+
to the `CredentialsConfig` struct in the Cluster Profile API, as specified in the next section, so that cluster-specific information, if applicable,
342+
can be discovered via the Cluster Profile API. It can also be used to allow other forms of extensions.
343+
344+
#### `AdditionalInfo`
345+
346+
The `AdditionalInfo` field in the `CredentialsConfig` struct, as added by this KEP to the Cluster Profile API, holds additional information that might help
347+
the credential provider code complete the authentication workflow. Each additional information entry is uniquely identified by a name, and features
348+
a piece of arbitrary data; it is up to the credential provider code the process and apply the data.
349+
350+
Furthermore, for authentication with exec plugins, this KEP reserves the following two names and dictates how the additional information should be
351+
formatted and used under the two names:
352+
353+
* `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-args`
354+
355+
This extension type supplies additional arguments that should be added when calling an exec plugin; if the credential provider code features its own set of
356+
arguments to use locally, the additional arguments in this extension should be appended. This might be useful in cases where the authentication workflow
357+
requires cluster-specific information, such as audiences, IDs, etc. Secrets or any form of sensitive data should not be stored in this extension.
358+
359+
The additional arguments should be stored as a string array in the YAML format.
360+
361+
* `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-envs`
362+
363+
This extension type supplies additional environment variables that should be unioned to other environment variables when calling an exec plugin; if the
364+
credential provider code features its own set of environment variables to add locally, the additional variables in this extension should be appended.
365+
This might also be useful in cases where the authentication workflow requires cluster-specific information, such as audiences, IDs, etc.
366+
Secrets or any form of sensitive data should not be kept in this extension.
367+
368+
The additional environment variables should be stored as a mapping between strings in the YAML format.
369+
293370

294371
#### ClusterProfile Example
295372

@@ -312,9 +389,9 @@ status:
312389
- name: location
313390
value: us-central1
314391
credentialProviders:
315-
- name: google
316-
cluster:
317-
server: https://connectgateway.googleapis.com/v1/projects/123456789/locations/us-central1/gkeMemberships/my-cluster-1
392+
google:
393+
cluster:
394+
server: https://connectgateway.googleapis.com/v1/projects/123456789/locations/us-central1/gkeMemberships/my-cluster-1
318395
```
319396

320397

0 commit comments

Comments
 (0)