Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,8 @@ controller, applications or consumers without requiring changes. It also cannot
is not sensitive.

The definition is as follows:
```

```golang
type CredentialProviders struct {
// +listType=map
// +listMapKey=name
Expand All @@ -237,7 +238,7 @@ type CredentialsType string
// CredentialsConfig gives more details on data that is necessary to reach out the cluster for this kind of Credentials
type CredentialsConfig struct {
Name string // name of the provider type
Cluster *Cluster // Configuration to reach the cluster (endpoints, proxy, etc) // See following section for details.
Cluster *Cluster // Configuration to reach the cluster (endpoints, proxy, etc) // See the sections below for details.
}
```

Expand Down Expand Up @@ -290,10 +291,85 @@ In this structure, not all fields would apply, such as:

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

##### About the `Extensions` field

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

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
`rest.Config` and return it to the caller based on some user-supplied exec plugin information, which already features an `ExecConfig` struct
(with the path to the exec plugin, arguments, environment variables, etc.) before it reads a `ClusterProfile` object; if the `ClusterProfile` object
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
in `ExecConfig.Config` should be sourced from `Cluster.Extensions`). To address this conflict, this KEP proposes that:

* If the `Cluster` struct in a `ClusterProfile` object already features some extension data under the name `client.authentication.k8s.io/exec`, the community
library will overwrite the `ExecConfig.Config` field with the data from the `ClusterProfile` object. It is up to the `ProvideClusterInfo` flag, which is
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`.

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
`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
`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
`KUBERNETES_EXEC_INFO` environment variable, and can be processed properly by the target exec plugin. The community-provided library will not perform
additional validation on the extension data.

##### Supplying additional CLI arguments and environment variables to the exec plugin

The current `Extensions` interface for passing additional cluster-specific authentication information might not be very easy for users to use. The presence
of the `KUBERNETES_EXEC_INFO` environment variable is purely optional; if the `ProvideClusterInfo` flag is unset (the default), this variable will be absent.
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
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.
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
embedded extension data will be properly extracted.

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
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
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
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
CLI arguments or environment variables, it would be fairly difficult to achieve this when using the Cluster Profile API and community-provided library.

To address this decifiency, we further proposes that:

* 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
supplied to the exec plugin when the Cluster Profile API and community-provided library are used for authentication.

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
(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.

The additional arguments should be represented as a string array in the YAML format.

For simplicity reasons, the community-provided library will not perform any de-duplication on the CLI arguments after appending the additional arguments.

* this KEP reserve another name in the extensions, `multicluster.x-k8s.io/clusterprofiles/auth/exec/additional-envs`, which holds additional environment variables
that need to be supplied upon calling the exec plugin when the Cluster Profile API and community-provided library are used for authentication.

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
(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.

The additional environment variables should be represented as a mapping between strings in the YAML format.

The community-provided library will de-duplicate the list of environment variables when adding the additional variables; if two entries are present under the
same name, the one from the extension will prevail.

###### Security concerns

With the addition of newly reserved extensions, understandably there might be situations where users might want to block additional CLI arguments or
environment variables from being set due to security reasons. To solve this, the KEP proposes that the community-provided library implementation must provide
two flags, `allowAdditionalCLIArgsExtension` and `allowAdditionalEnvVarExtension`, that control whether additional CLI arguments or environment
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.


#### ClusterProfile Example

Example of a GKE ClusterProfile, which would map to a plugin providing credentials of type `google`:

```
apiVersion: multicluster.x-k8s.io/v1alpha1
kind: ClusterProfile
Expand Down