From 08566af7c1a4a7b3679a3cdf4c424232ba686696 Mon Sep 17 00:00:00 2001 From: Dmytro Bondar Date: Thu, 28 Nov 2024 14:44:30 +0100 Subject: [PATCH] fix: handle managed identity ClientID or ResourceID in acr generator (#4150) * fix: use ClientID instead of ResourceID in acr generator Signed-off-by: Dmytro Bondar * Handle both cases: with ClientID and ResourceID Signed-off-by: Dmytro Bondar * Update ACR docs Signed-off-by: Dmytro Bondar --------- Signed-off-by: Dmytro Bondar --- docs/api/generator/acr.md | 10 ++++- .../generator-acr-argocd-helm-repo.yaml | 38 +++++++++++++++++++ docs/snippets/generator-acr.yaml | 6 +-- pkg/generator/acr/acr.go | 16 +++++--- 4 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 docs/snippets/generator-acr-argocd-helm-repo.yaml diff --git a/docs/api/generator/acr.md b/docs/api/generator/acr.md index d5777ca7d..8a5aa7d7f 100644 --- a/docs/api/generator/acr.md +++ b/docs/api/generator/acr.md @@ -9,7 +9,6 @@ The token is generated for a particular ACR registry defined in `spec.registry`. | username | username for the `docker login` command | | password | password for the `docker login` command | - ## Authentication You must choose one out of three authentication mechanisms: @@ -21,6 +20,8 @@ You must choose one out of three authentication mechanisms: The generated token will inherit the permissions from the assigned policy. I.e. when you assign a read-only policy all generated tokens will be read-only. You **must** [assign a Azure RBAC role](https://learn.microsoft.com/en-us/azure/role-based-access-control/role-assignments-steps), such as `AcrPush` or `AcrPull` to the service principal or managed identity in order to be able to authenticate with the Azure container registry API. +You can also use a kubelet managed identity with the default `AcrPull` role to authenticate to the integrated Azure Container Registry. + You can scope tokens to a particular repository using `spec.scope`. ## Scope @@ -49,6 +50,13 @@ repository:my-repository:pull ``` Example `ExternalSecret` that references the ACR generator: + ```yaml {% include 'generator-acr-example.yaml' %} ``` + +Example using AKS kubelet managed identity to create [Argo CD helm chart repository](https://argo-cd.readthedocs.io/en/latest/operator-manual/declarative-setup/#helm-chart-repositories) secret: + +```yaml +{% include 'generator-acr-argocd-helm-repo.yaml' %} +``` diff --git a/docs/snippets/generator-acr-argocd-helm-repo.yaml b/docs/snippets/generator-acr-argocd-helm-repo.yaml new file mode 100644 index 000000000..9fc7b9b4d --- /dev/null +++ b/docs/snippets/generator-acr-argocd-helm-repo.yaml @@ -0,0 +1,38 @@ +{% raw %} +apiVersion: generators.external-secrets.io/v1alpha1 +kind: ACRAccessToken +metadata: + name: azurecr +spec: + tenantId: 11111111-2222-3333-4444-111111111111 + registry: example.azurecr.io + auth: + managedIdentity: + identityId: 11111111-2222-3333-4444-111111111111 +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: azurecr-credentials +spec: + dataFrom: + - sourceRef: + generatorRef: + apiVersion: generators.external-secrets.io/v1alpha1 + kind: ACRAccessToken + name: azurecr + refreshInterval: 3h + target: + name: azurecr-credentials + template: + metadata: + labels: + argocd.argoproj.io/secret-type: repository + data: + name: "example.azurecr.io" + url: "example.azurecr.io" + username: "{{ .username }}" + password: "{{ .password }}" + enableOCI: "true" + type: "helm" +{% endraw %} diff --git a/docs/snippets/generator-acr.yaml b/docs/snippets/generator-acr.yaml index 49093480a..13468e1e7 100644 --- a/docs/snippets/generator-acr.yaml +++ b/docs/snippets/generator-acr.yaml @@ -28,13 +28,13 @@ spec: name: az-secret key: clientid - # option 2: + # option 2: use a managed identity Client ID managedIdentity: - identityId: "xxxxx" + identityId: 11111111-2222-3333-4444-111111111111 # option 3: workloadIdentity: # note: you can reference service accounts across namespaces. serviceAccountRef: name: "my-service-account" - audiences: [] \ No newline at end of file + audiences: [] diff --git a/pkg/generator/acr/acr.go b/pkg/generator/acr/acr.go index 7f7ca48a2..fa6b0daa8 100644 --- a/pkg/generator/acr/acr.go +++ b/pkg/generator/acr/acr.go @@ -282,12 +282,18 @@ func accessTokenForWorkloadIdentity(ctx context.Context, crClient client.Client, } func accessTokenForManagedIdentity(ctx context.Context, envType v1beta1.AzureEnvironmentType, identityID string) (string, error) { - // handle workload identity - creds, err := azidentity.NewManagedIdentityCredential( - &azidentity.ManagedIdentityCredentialOptions{ + // handle managed identity + var opts *azidentity.ManagedIdentityCredentialOptions + if strings.Contains(identityID, "/") { + opts = &azidentity.ManagedIdentityCredentialOptions{ ID: azidentity.ResourceID(identityID), - }, - ) + } + } else { + opts = &azidentity.ManagedIdentityCredentialOptions{ + ID: azidentity.ClientID(identityID), + } + } + creds, err := azidentity.NewManagedIdentityCredential(opts) if err != nil { return "", err }