|
|
|
@ -9,7 +9,7 @@ Must be one of `provisional`, `implementable`, `implemented`, `deferred`, `rejec
|
|
|
|
|
|
|
|
|
|
**Creation date:** 2025-02-22
|
|
|
|
|
|
|
|
|
|
**Last update:** 2025-04-14
|
|
|
|
|
**Last update:** 2025-04-17
|
|
|
|
|
|
|
|
|
|
## Summary
|
|
|
|
|
|
|
|
|
@ -550,10 +550,19 @@ annotations are required in the Kubernetes `ServiceAccount`. Another improvement
|
|
|
|
|
from this EKS feature compared to *IAM Roles for Service Accounts* is that users
|
|
|
|
|
no longer need to create an *OIDC Provider* for the EKS cluster in the IAM API.
|
|
|
|
|
|
|
|
|
|
It should be noted, however, that in the feature proposed here we cannot support
|
|
|
|
|
*EKS Pod Identity* because it requires the `ServiceAccount` token to be bound to
|
|
|
|
|
a pod, and the Kubernetes API will only issue a `ServiceAccount` token bound to a
|
|
|
|
|
pod if that pod uses the respective `ServiceAccount`, which is a requirement we
|
|
|
|
|
simply cannot meet. The only pod guaranteed to exist from the perspective of a
|
|
|
|
|
Flux controller is itself. Therefore, it's impossible to support EKS Pod Identity
|
|
|
|
|
for multi-tenant workload identity. (It is already possible to use it for
|
|
|
|
|
single-tenant workload identity, though.)
|
|
|
|
|
|
|
|
|
|
In sight of the technical background presented above, our proposal becomes simpler.
|
|
|
|
|
The only solution to support multi-tenant workload identity at the object-level for
|
|
|
|
|
the Flux APIs is to associate the Flux objects with Kubernetes `ServiceAccounts`.
|
|
|
|
|
We propose to build the `ServiceAccount` token creation and exchange logic into
|
|
|
|
|
We propose building the `ServiceAccount` token creation and exchange logic into
|
|
|
|
|
the Flux controllers through a library in the `github.com/fluxcd/pkg` repository.
|
|
|
|
|
|
|
|
|
|
### API Changes
|
|
|
|
@ -707,7 +716,7 @@ type Provider interface {
|
|
|
|
|
// ServiceAccounts should have. This is usually a string that represents
|
|
|
|
|
// the cloud provider's STS service, or some entity in the provider for
|
|
|
|
|
// which the OIDC tokens are targeted to.
|
|
|
|
|
GetAudience(ctx context.Context, sa corev1.ServiceAccount) (string, error)
|
|
|
|
|
GetAudience(ctx context.Context) (string, error)
|
|
|
|
|
|
|
|
|
|
// GetIdentity takes a ServiceAccount and returns the identity which the
|
|
|
|
|
// ServiceAccount wants to impersonate, by looking at annotations.
|
|
|
|
@ -941,7 +950,6 @@ only once into a package variable.
|
|
|
|
|
The cache key must include the following components:
|
|
|
|
|
|
|
|
|
|
* The cloud provider name.
|
|
|
|
|
* The provider audience used for issuing the Kubernetes `ServiceAccount` token.
|
|
|
|
|
* The optional `ServiceAccount` reference and cloud provider identity.
|
|
|
|
|
The identity is the string representing the identity which the `ServiceAccount`
|
|
|
|
|
is impersonating, e.g. for `gcp` this would be a GCP IAM Service Account email,
|
|
|
|
@ -960,13 +968,6 @@ the controller is the one represented by the token, so there is no identity or
|
|
|
|
|
with the controller. In this case, including only the cloud provider name in the
|
|
|
|
|
cache key is enough.
|
|
|
|
|
|
|
|
|
|
The provider audience used for issuing the `ServiceAccount` token is included
|
|
|
|
|
in the cache key because it may depend on the `ServiceAccount` annotations.
|
|
|
|
|
For example, in AWS if an IAM Role ARN is not specified we assume that users
|
|
|
|
|
are attempting to use EKS Pod Identity instead of IAM Roles for Service
|
|
|
|
|
Accounts. Each feature has its own audience string and its own way of issuing
|
|
|
|
|
tokens, so the audience string must be included in the cache key.
|
|
|
|
|
|
|
|
|
|
In multi-tenant workload identity, the reason for including both the `ServiceAccount`
|
|
|
|
|
and the identity in the cache key is to establish the fact that the `ServiceAccount`
|
|
|
|
|
had permission to impersonate the identity at the time when the token was issued.
|
|
|
|
@ -1024,7 +1025,6 @@ Multi-tenant/object-level:
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
provider=<cloud-provider-name>,
|
|
|
|
|
providerAudience=<cloud-provider-audience>,
|
|
|
|
|
serviceAccountName=<service-account-name>,
|
|
|
|
|
serviceAccountNamespace=<service-account-namespace>,
|
|
|
|
|
cloudProviderIdentity=<cloud-provider-identity>,
|
|
|
|
@ -1078,13 +1078,6 @@ a different identity or deleting the `ServiceAccount` altogether, as the control
|
|
|
|
|
`ServiceAccount` should not be deleted. The best mitigation in this case is to restart
|
|
|
|
|
the Flux controllers so the cache is purged.
|
|
|
|
|
|
|
|
|
|
**EKS Pod Identity**: In EKS Pod Identity the association between a `ServiceAccount`
|
|
|
|
|
and an IAM Role is not configured on the `ServiceAccount` annotations, nor anywhere
|
|
|
|
|
else inside the Kubernetes cluster. The association is established entirely through
|
|
|
|
|
the EKS/IAM APIs. In this case, all the mitigations mentioned above apply, except
|
|
|
|
|
for the one that involves changing the annotations of the `ServiceAccount`, as there
|
|
|
|
|
are no annotations to change.
|
|
|
|
|
|
|
|
|
|
### Library Integration
|
|
|
|
|
|
|
|
|
|
When reconciling an object, the controller must use the `auth.GetToken()`
|
|
|
|
|