Skip to content

Commit 1cbec78

Browse files
michaelawyumichaelawyu
authored andcommitted
Minor fixes
Signed-off-by: michaelawyu <[email protected]>
1 parent b96d925 commit 1cbec78

File tree

1 file changed

+50
-51
lines changed
  • keps/sig-multicluster/5339-clusterprofile-plugin-credentials

1 file changed

+50
-51
lines changed

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

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,10 @@ type CredentialProviders struct {
235235
// 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`.
236236
type CredentialsType string
237237

238-
// AdditionalInformation is a piece of additional information with a nickname.
239-
type AdditionalInformation struct {
240-
Name string
241-
Data runtime.RawExtension
242-
}
243-
244238
// CredentialsConfig gives more details on data that is necessary to reach out the cluster for this kind of Credentials
245239
type CredentialsConfig struct {
246240
Name string // name of the provider type
247241
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.
249242
}
250243
```
251244

@@ -300,77 +293,83 @@ In this structure, not all fields would apply, such as:
300293

301294
##### About the `Extensions` field
302295

303-
The `Cluster` struct defined in `client-go` ([link](https://github.com/kubernetes/client-go/blob/d32752779319f587c42ff9edbc6ed533575f2136/tools/clientcmd/api/types.go#L69))
296+
The `Cluster` type defined in `client-go` ([link](https://github.com/kubernetes/client-go/blob/d32752779319f587c42ff9edbc6ed533575f2136/tools/clientcmd/api/types.go#L69)),
297+
which is also a struct in use by the `CredentialsConfig` type from this KEP,
304298
features a field, `extensions`, for holding additional information about the cluster, with each extension associated with a name.
305299
[KEP-541](https://github.com/kubernetes/enhancements/blob/master/keps/sig-auth/541-external-credential-providers/README.md) further reserves a name,
306300
`client.authentication.k8s.io/exec`, for per-cluster additional information for authentication exec plugins.
307301
Per KEP-541's explanation, if the `client.authentication.k8s.io/exec` extension has been set in the `Cluster` struct, the data shall be
308302
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)).
309303
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)),
304+
`Cluster` struct (from the `client.authentication.k8s.io` API group, see [link](https://pkg.go.dev/k8s.io/client-go/pkg/apis/clientauthentication#Cluster)),
311305
which includes the parsed extension data (`Config` field in the `ExecConfig` struct), and save it to an environment variable, `KUBERNETES_EXEC_INFO`.
312306

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
307+
For the workflow defined in this KEP, however, as described earlier in this document, it is up to the community-provided library to build a
314308
`rest.Config` and return it to the caller based on some user-supplied exec plugin information, which already features an `ExecConfig` struct
315309
(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:
310+
has extensions set, it might be in conflict with the `ExecConfig.Config` field that the community-provided library sees (typically, as KEP-541 dictates, data
311+
in `ExecConfig.Config` should be sourced from `Cluster.Extensions`). To address this conflict, this KEP proposes that:
312+
313+
* If the `Cluster` struct in a `ClusterProfile` object already features some extension data under the name `client.authentication.k8s.io/exec`, the community
314+
library will overwrite the `ExecConfig.Config` field with the data from the `ClusterProfile` object. It is up to the `ProvideClusterInfo` flag, which is
315+
set exclusively on the community-provided library side, to decide whether this extension data will be provided as a part of the environment variable, `KUBERNETES_EXEC_INFO`.
318316

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).
317+
In addition, as the extension data under the name `client.authentication.k8s.io/exec` is provided in the form of a `runtime.RawExtension` struct, and the
318+
`ExecConfig.Config` field accepts only a `runtime.Object` interface, the community-provided library will attempt to bridge the two by saving the extension data as a
319+
`runtime.Unknown` struct. It is up to the user to ensure that the extension data is of a correct format that can be serialized/deserialized when being saved as the
320+
`KUBERNETES_EXEC_INFO` environment variable, and can be processed properly by the target exec plugin. The community-provided library will not perform
321+
additional validation on the extension data.
328322

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:
323+
##### Supplying additional CLI arguments and environment variables to the exec plugin
331324

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.
325+
The current `Extensions` interface for passing additional cluster-specific authentication information might not be very easy for users to use. The presence
326+
of the `KUBERNETES_EXEC_INFO` environment variable is purely optional; if the `ProvideClusterInfo` flag is unset (the default), this variable will be absent.
327+
There are a few cases where the variable cannot be easily set: for example, the `KUBERNETES_EXEC_INFO` environment variable does feature the CA bundle for the
328+
target cluster, which can potentially get quite large; depending on the target environment, it might not be OK to write such data as an environment variable.
329+
Exec plugins are not mandated to support this environment variable either; even for those that do read this environment variable, it is not guaranteed that any
330+
embedded extension data will be properly extracted.
336331

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.
332+
On the other hand, it is quite common for multi-cluster users to have a need for specifying cluster-specific information when performing the authentication
333+
workflow: the authentication solution in use by a cluster might be expecting a token of a specific audience, or a token from a specific identity. Most, if not
334+
all, exec plugins would expect such information from the CLI arguments or some environment variables. In a single-cluster setup, it is trivial to set them up, as the
335+
user has direct control over the `ExecConfig` struct; however, for the multi-cluster setup, since the `Cluster` struct does not feature any fields for additional
336+
CLI arguments or environment variables, it would be fairly difficult to achieve this when using the Cluster Profile API and community-provided library.
343337

344-
#### `AdditionalInfo`
338+
To address this decifiency, we further proposes that:
345339

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.
340+
* this KEP reserve a name in the extensions, `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-args`, which holds additional CLI arguments that need to be
341+
supplied to the exec plugin when the Cluster Profile API and community-provided library are used for authentication.
349342

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:
343+
If an extension under this name is present, the community-provided library will extract the data, and append the additional arguments to the `ExecConfig` struct
344+
(specifically the `ExecConfig.Args` field) that will be used to prepare the `rest.Config` output. The arguments will then be used to invoke the exec plugin.
352345

353-
* `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-args`
346+
The additional arguments should be represented as a string array in the YAML format.
354347

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.
348+
For simplicity reasons, the community-provided library will not perform any de-duplication on the CLI arguments after appending the additional arguments.
358349

359-
The additional arguments should be stored as a string array in the YAML format.
350+
* this KEP reserve another name in the extensions, `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-envs`, which holds additional environment variables
351+
that need to be supplied upon calling the exec plugin when the Cluster Profile API and community-provided library are used for authentication.
360352

361-
* `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-envs`
353+
If an extension under this name is present, the community-provided library will extract the data, and add the additional variables to the `ExecConfig` struct
354+
(specifically the `ExecConfig.Env` field) that will be used to prepare the `rest.Config` output. The variables will then be set when invoking the exec plugin.
362355

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.
356+
The additional environment variables should be represented as a mapping between strings in the YAML format.
367357

368-
The additional environment variables should be stored as a mapping between strings in the YAML format.
358+
The community-provided library will de-duplicate the list of environment variables when adding the additional variables; if two entries are present under the
359+
same name, the one from the extension will prevail.
360+
361+
###### Security concerns
362+
363+
With the addition of newly reserved extensions, understandably there might be situations where users might want to block additional CLI arguments or
364+
environment variables from being set due to security reasons. To solve this, the KEP proposes that the community-provided library implementation must provide
365+
two flags, `allowAdditionalCLIArgsExtension` and `allowAdditionalEnvVarExtension`, that control whether additional CLI arguments or environment
366+
variables will be read from a `ClusterProfile` object respectively. A reserved extension will be not processed if the corresponding flag is unset. By default both flags should be unset.
369367

370368

371369
#### ClusterProfile Example
372370

373371
Example of a GKE ClusterProfile, which would map to a plugin providing credentials of type `google`:
372+
374373
```
375374
apiVersion: multicluster.x-k8s.io/v1alpha1
376375
kind: ClusterProfile
@@ -391,7 +390,7 @@ status:
391390
credentialProviders:
392391
- name: google
393392
cluster:
394-
server: https://connectgateway.googleapis.com/v1/projects/123456789/locations/us-central1/gkeMemberships/my-cluster-1
393+
server: https://connectgateway.googleapis.com/v1/projects/123456789/locations/us-central1/gkeMemberships/my-cluster-1
395394
```
396395

397396

0 commit comments

Comments
 (0)