From 072db4469e6d033007772616d5128152f1f211bf Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Mon, 14 Aug 2023 11:44:20 +1200 Subject: [PATCH 01/11] Add pod identity support for namespaces and per-resource scoped auth --- .../guide/authentication/credential-format.md | 110 +++++++++++++++--- v2/internal/identity/credential_provider.go | 21 ++++ v2/pkg/common/config/config.go | 2 + 3 files changed, 119 insertions(+), 14 deletions(-) diff --git a/docs/hugo/content/guide/authentication/credential-format.md b/docs/hugo/content/guide/authentication/credential-format.md index 661ac12a2de..0328409d053 100644 --- a/docs/hugo/content/guide/authentication/credential-format.md +++ b/docs/hugo/content/guide/authentication/credential-format.md @@ -448,7 +448,7 @@ export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n $ export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)" ``` -#### Manual Deploy +#### Manual Deployment Deploy an `AzureIdentity`: ```bash @@ -479,7 +479,46 @@ spec: EOF ``` -Deploy the `aso-controller-settings` secret, configured to use the identity: +#### Helm Chart Deployment + +```bash +helm repo add aso2 https://raw.githubusercontent.com/Azure/azure-service-operator/main/v2/charts +helm repo update + +helm upgrade --install --devel aso2 aso2/azure-service-operator \ + --create-namespace \ + --namespace=azureserviceoperator-system \ + --set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \ + --set aadPodIdentity.enable=true \ + --set aadPodIdentity.azureManagedIdentityResourceId=${IDENTITY_RESOURCE_ID} \ + --set azureClientID=${IDENTITY_CLIENT_ID} \ + --set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*' +``` + +See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. + +#### Create the secret + +{{< tabpane text=true left=true >}} +{{% tab header="**Scope**:" disabled=true /%}} +{{% tab header="Global" %}} + +If installing ASO for the first time, you can pass these values via Helm arguments: +```bash +helm upgrade --install --devel aso2 aso2/azure-service-operator \ + --create-namespace \ + --namespace=azureserviceoperator-system \ + --set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \ + --set aadPodIdentity.enable=true \ + --set aadPodIdentity.azureManagedIdentityResourceId=${IDENTITY_RESOURCE_ID} \ + --set azureClientID=${IDENTITY_CLIENT_ID} \ + --set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*' +``` + +See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. + +Otherwise, create or update the `aso-controller-settings` secret: + ```bash cat <}} ) in that secret are not being overwritten. + +{{% /tab %}} +{{% tab header="Namespace" %}} +Create the `aso-credential` secret in your namespace: ```bash -helm repo add aso2 https://raw.githubusercontent.com/Azure/azure-service-operator/main/v2/charts -helm repo update +cat <}} ) for more details about `crdPattern`. \ No newline at end of file +{{% /tab %}} +{{< /tabpane >}} diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 3dd8325558c..22e2a6dda02 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -8,6 +8,7 @@ package identity import ( "context" "reflect" + "strconv" "strings" "github.com/Azure/azure-sdk-for-go/sdk/azcore" @@ -258,6 +259,26 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } + if usePodIdentity, hasUsePodIdentity := secret.Data[config.UseAzurePodIdentityAuth]; hasUsePodIdentity { + if usePodIdentityBool, _ := strconv.ParseBool(string(usePodIdentity)); usePodIdentityBool { + tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ + ClientOptions: azcore.ClientOptions{}, + ID: azidentity.ClientID(usePodIdentity), + }) + + if err != nil { + return nil, errors.Wrap(err, errors.Errorf("invalid Identity for %q encountered", nsName).Error()) + } + + return &Credential{ + tokenCredential: tokenCredential, + subscriptionID: string(subscriptionID), + credentialFrom: nsName, + secretData: secret.Data, + }, nil + } + } + // Here we check for workload identity if client secret is not provided. tokenCredential, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{ ClientID: string(clientID), diff --git a/v2/pkg/common/config/config.go b/v2/pkg/common/config/config.go index f969d094c6b..a8f340a6d2c 100644 --- a/v2/pkg/common/config/config.go +++ b/v2/pkg/common/config/config.go @@ -53,6 +53,8 @@ const ( AzureAuthorityHost = "AZURE_AUTHORITY_HOST" // PodNamespace is the namespace the operator pods are running in. PodNamespace = "POD_NAMESPACE" + // UseAzurePodIdentityAuth boolean is used to determine if we're using Pod Identity authentication for namespace and per-resource scoped credentials + UseAzurePodIdentityAuth = "USE_POD_IDENTITY_AUTH" // UseWorkloadIdentityAuth boolean is used to determine if we're using Workload Identity authentication for global credential UseWorkloadIdentityAuth = "USE_WORKLOAD_IDENTITY_AUTH" ) From 5fbfce63b2e151eb4bf11168599adf2e49c13ae3 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Mon, 14 Aug 2023 14:44:04 +1200 Subject: [PATCH 02/11] Add comment and update ID var --- v2/internal/identity/credential_provider.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 22e2a6dda02..07f1184bd31 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -260,14 +260,15 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden } if usePodIdentity, hasUsePodIdentity := secret.Data[config.UseAzurePodIdentityAuth]; hasUsePodIdentity { + // Ignoring error here, as any other value or empty value means we should default to false if usePodIdentityBool, _ := strconv.ParseBool(string(usePodIdentity)); usePodIdentityBool { tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ ClientOptions: azcore.ClientOptions{}, - ID: azidentity.ClientID(usePodIdentity), + ID: azidentity.ClientID(clientID), }) if err != nil { - return nil, errors.Wrap(err, errors.Errorf("invalid Identity for %q encountered", nsName).Error()) + return nil, errors.Wrap(err, errors.Errorf("invalid Managed Identity for %q encountered", nsName).Error()) } return &Credential{ From 14b842773961318bd2050d15ccaf280a3880da2e Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Mon, 14 Aug 2023 15:27:11 +1200 Subject: [PATCH 03/11] Update documentation --- .../guide/authentication/credential-format.md | 127 ++++++++++++------ 1 file changed, 84 insertions(+), 43 deletions(-) diff --git a/docs/hugo/content/guide/authentication/credential-format.md b/docs/hugo/content/guide/authentication/credential-format.md index 0328409d053..5d9bcd49b32 100644 --- a/docs/hugo/content/guide/authentication/credential-format.md +++ b/docs/hugo/content/guide/authentication/credential-format.md @@ -448,7 +448,29 @@ export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n $ export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)" ``` -#### Manual Deployment +See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. + +### Create the secret + +{{< tabpane text=true left=true >}} +{{% tab header="**Scope**:" disabled=true /%}} +{{% tab header="Global" %}} + +If installing ASO for the first time, you can pass these values via Helm arguments: +```bash +helm upgrade --install --devel aso2 aso2/azure-service-operator \ + --create-namespace \ + --namespace=azureserviceoperator-system \ + --set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \ + --set aadPodIdentity.enable=true \ + --set aadPodIdentity.azureManagedIdentityResourceId=${IDENTITY_RESOURCE_ID} \ + --set azureClientID=${IDENTITY_CLIENT_ID} \ + --set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*' +``` + +See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. + +Otherwise, if deploying manually: Deploy an `AzureIdentity`: ```bash @@ -479,46 +501,7 @@ spec: EOF ``` -#### Helm Chart Deployment - -```bash -helm repo add aso2 https://raw.githubusercontent.com/Azure/azure-service-operator/main/v2/charts -helm repo update - -helm upgrade --install --devel aso2 aso2/azure-service-operator \ - --create-namespace \ - --namespace=azureserviceoperator-system \ - --set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \ - --set aadPodIdentity.enable=true \ - --set aadPodIdentity.azureManagedIdentityResourceId=${IDENTITY_RESOURCE_ID} \ - --set azureClientID=${IDENTITY_CLIENT_ID} \ - --set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*' -``` - -See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. - -#### Create the secret - -{{< tabpane text=true left=true >}} -{{% tab header="**Scope**:" disabled=true /%}} -{{% tab header="Global" %}} - -If installing ASO for the first time, you can pass these values via Helm arguments: -```bash -helm upgrade --install --devel aso2 aso2/azure-service-operator \ - --create-namespace \ - --namespace=azureserviceoperator-system \ - --set azureSubscriptionID=$AZURE_SUBSCRIPTION_ID \ - --set aadPodIdentity.enable=true \ - --set aadPodIdentity.azureManagedIdentityResourceId=${IDENTITY_RESOURCE_ID} \ - --set azureClientID=${IDENTITY_CLIENT_ID} \ - --set crdPattern='resources.azure.com/*;containerservice.azure.com/*;keyvault.azure.com/*;managedidentity.azure.com/*;eventhub.azure.com/*' -``` - -See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. - -Otherwise, create or update the `aso-controller-settings` secret: - +Create or update the `aso-controller-settings` secret: ```bash cat < Date: Fri, 25 Aug 2023 15:01:49 +1200 Subject: [PATCH 04/11] Add enum for Identity mode --- .../guide/authentication/credential-format.md | 16 +++--- v2/internal/identity/credential_provider.go | 57 ++++++++++++------- v2/pkg/common/config/config.go | 2 - 3 files changed, 46 insertions(+), 29 deletions(-) diff --git a/docs/hugo/content/guide/authentication/credential-format.md b/docs/hugo/content/guide/authentication/credential-format.md index 5d9bcd49b32..820be63700a 100644 --- a/docs/hugo/content/guide/authentication/credential-format.md +++ b/docs/hugo/content/guide/authentication/credential-format.md @@ -139,8 +139,9 @@ metadata: namespace: my-namespace stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" - AZURE_TENANT_ID: "$AZURE_TENANT_ID" - AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" + AZURE_TENANT_ID: "$AZURE_TENANT_ID" + AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" + IDENTITY_AUTH_MODE: "workload" EOF ``` @@ -160,8 +161,9 @@ metadata: namespace: my-namespace stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" - AZURE_TENANT_ID: "$AZURE_TENANT_ID" - AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" + AZURE_TENANT_ID: "$AZURE_TENANT_ID" + AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" + IDENTITY_AUTH_MODE: "workload" EOF ``` @@ -448,8 +450,6 @@ export IDENTITY_CLIENT_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n $ export IDENTITY_RESOURCE_ID="$(az identity show -g ${IDENTITY_RESOURCE_GROUP} -n ${IDENTITY_NAME} --query id -otsv)" ``` -See [CRD management]( {{< relref "crd-management" >}} ) for more details about `crdPattern`. - ### Create the secret {{< tabpane text=true left=true >}} @@ -564,7 +564,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - USE_POD_IDENTITY_AUTH: "true" + IDENTITY_AUTH_MODE: "pod" EOF ``` @@ -612,7 +612,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - USE_POD_IDENTITY_AUTH: "true" + IDENTITY_AUTH_MODE: "pod" EOF ``` diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 07f1184bd31..389eeb8afdd 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -8,7 +8,6 @@ package identity import ( "context" "reflect" - "strconv" "strings" "github.com/Azure/azure-sdk-for-go/sdk/azcore" @@ -35,6 +34,17 @@ const ( FederatedTokenFilePath = "/var/run/secrets/tokens/azure-identity" ) +type IdentityAuthModeOption string + +const ( + podIdentity IdentityAuthModeOption = "pod" + workloadIdentity IdentityAuthModeOption = "workload" + + // IdentityAuthMode enum is used to determine if we're using Pod Identity or Workload Identity + //authentication for namespace and per-resource scoped credentials + IdentityAuthMode = "IDENTITY_AUTH_MODE" +) + // Credential describes a credential used to connect to Azure type Credential struct { tokenCredential azcore.TokenCredential @@ -259,25 +269,27 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - if usePodIdentity, hasUsePodIdentity := secret.Data[config.UseAzurePodIdentityAuth]; hasUsePodIdentity { - // Ignoring error here, as any other value or empty value means we should default to false - if usePodIdentityBool, _ := strconv.ParseBool(string(usePodIdentity)); usePodIdentityBool { - tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ - ClientOptions: azcore.ClientOptions{}, - ID: azidentity.ClientID(clientID), - }) - - if err != nil { - return nil, errors.Wrap(err, errors.Errorf("invalid Managed Identity for %q encountered", nsName).Error()) - } - - return &Credential{ - tokenCredential: tokenCredential, - subscriptionID: string(subscriptionID), - credentialFrom: nsName, - secretData: secret.Data, - }, nil + var authMode IdentityAuthModeOption + if value, hasUsePodIdentity := secret.Data[IdentityAuthMode]; hasUsePodIdentity { + authMode = authModeOrDefault(string(value)) + } + + if authMode == podIdentity { + tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ + ClientOptions: azcore.ClientOptions{}, + ID: azidentity.ClientID(clientID), + }) + + if err != nil { + return nil, errors.Wrap(err, errors.Errorf("invalid Managed Identity for %q encountered", nsName).Error()) } + + return &Credential{ + tokenCredential: tokenCredential, + subscriptionID: string(subscriptionID), + credentialFrom: nsName, + secretData: secret.Data, + }, nil } // Here we check for workload identity if client secret is not provided. @@ -322,3 +334,10 @@ func (c *credentialProvider) getSecret(ctx context.Context, namespace string, se func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string) types.NamespacedName { return types.NamespacedName{Namespace: resourceNamespace, Name: credentialFrom} } + +func authModeOrDefault(mode string) IdentityAuthModeOption { + if mode == string(podIdentity) { + return podIdentity + } + return workloadIdentity +} diff --git a/v2/pkg/common/config/config.go b/v2/pkg/common/config/config.go index a8f340a6d2c..f969d094c6b 100644 --- a/v2/pkg/common/config/config.go +++ b/v2/pkg/common/config/config.go @@ -53,8 +53,6 @@ const ( AzureAuthorityHost = "AZURE_AUTHORITY_HOST" // PodNamespace is the namespace the operator pods are running in. PodNamespace = "POD_NAMESPACE" - // UseAzurePodIdentityAuth boolean is used to determine if we're using Pod Identity authentication for namespace and per-resource scoped credentials - UseAzurePodIdentityAuth = "USE_POD_IDENTITY_AUTH" // UseWorkloadIdentityAuth boolean is used to determine if we're using Workload Identity authentication for global credential UseWorkloadIdentityAuth = "USE_WORKLOAD_IDENTITY_AUTH" ) From e92c5c8b8cf397622f985ebe38b0498dda4e3648 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Mon, 28 Aug 2023 12:08:46 +1200 Subject: [PATCH 05/11] Update IdentityAuthMode flag to AuthMode --- .../guide/authentication/credential-format.md | 8 ++++---- v2/internal/identity/credential_provider.go | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/docs/hugo/content/guide/authentication/credential-format.md b/docs/hugo/content/guide/authentication/credential-format.md index 820be63700a..4792179a0d3 100644 --- a/docs/hugo/content/guide/authentication/credential-format.md +++ b/docs/hugo/content/guide/authentication/credential-format.md @@ -141,7 +141,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" - IDENTITY_AUTH_MODE: "workload" + AUTH_MODE: "workload" EOF ``` @@ -163,7 +163,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" - IDENTITY_AUTH_MODE: "workload" + AUTH_MODE: "workload" EOF ``` @@ -564,7 +564,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - IDENTITY_AUTH_MODE: "pod" + AUTH_MODE: "pod" EOF ``` @@ -612,7 +612,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - IDENTITY_AUTH_MODE: "pod" + AUTH_MODE: "pod" EOF ``` diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 389eeb8afdd..2160301f670 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -34,15 +34,15 @@ const ( FederatedTokenFilePath = "/var/run/secrets/tokens/azure-identity" ) -type IdentityAuthModeOption string +type AuthModeOption string const ( - podIdentity IdentityAuthModeOption = "pod" - workloadIdentity IdentityAuthModeOption = "workload" + podIdentity AuthModeOption = "pod" + workloadIdentity AuthModeOption = "workload" - // IdentityAuthMode enum is used to determine if we're using Pod Identity or Workload Identity + // AuthMode enum is used to determine if we're using Pod Identity or Workload Identity //authentication for namespace and per-resource scoped credentials - IdentityAuthMode = "IDENTITY_AUTH_MODE" + AuthMode = "AUTH_MODE" ) // Credential describes a credential used to connect to Azure @@ -269,8 +269,8 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - var authMode IdentityAuthModeOption - if value, hasUsePodIdentity := secret.Data[IdentityAuthMode]; hasUsePodIdentity { + var authMode AuthModeOption + if value, hasUsePodIdentity := secret.Data[AuthMode]; hasUsePodIdentity { authMode = authModeOrDefault(string(value)) } @@ -335,7 +335,7 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string return types.NamespacedName{Namespace: resourceNamespace, Name: credentialFrom} } -func authModeOrDefault(mode string) IdentityAuthModeOption { +func authModeOrDefault(mode string) AuthModeOption { if mode == string(podIdentity) { return podIdentity } From 092d6d6b913281b4764426a53100f2030cbdcf68 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Tue, 29 Aug 2023 13:59:29 +1200 Subject: [PATCH 06/11] Update enum values; Update auth mode logic to return error --- .../guide/authentication/credential-format.md | 8 +++--- v2/internal/identity/credential_provider.go | 26 +++++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/docs/hugo/content/guide/authentication/credential-format.md b/docs/hugo/content/guide/authentication/credential-format.md index 4792179a0d3..4b65b3d84f6 100644 --- a/docs/hugo/content/guide/authentication/credential-format.md +++ b/docs/hugo/content/guide/authentication/credential-format.md @@ -141,7 +141,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" - AUTH_MODE: "workload" + AUTH_MODE: "workloadidentity" EOF ``` @@ -163,7 +163,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$AZURE_CLIENT_ID" - AUTH_MODE: "workload" + AUTH_MODE: "workloadidentity" EOF ``` @@ -564,7 +564,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - AUTH_MODE: "pod" + AUTH_MODE: "podidentity" EOF ``` @@ -612,7 +612,7 @@ stringData: AZURE_SUBSCRIPTION_ID: "$AZURE_SUBSCRIPTION_ID" AZURE_TENANT_ID: "$AZURE_TENANT_ID" AZURE_CLIENT_ID: "$IDENTITY_CLIENT_ID" - AUTH_MODE: "pod" + AUTH_MODE: "podidentity" EOF ``` diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 2160301f670..ad980726beb 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -37,8 +37,8 @@ const ( type AuthModeOption string const ( - podIdentity AuthModeOption = "pod" - workloadIdentity AuthModeOption = "workload" + podIdentity AuthModeOption = "podidentity" + workloadIdentity AuthModeOption = "workloadidentity" // AuthMode enum is used to determine if we're using Pod Identity or Workload Identity //authentication for namespace and per-resource scoped credentials @@ -270,8 +270,13 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden } var authMode AuthModeOption + var err error if value, hasUsePodIdentity := secret.Data[AuthMode]; hasUsePodIdentity { - authMode = authModeOrDefault(string(value)) + authMode, err = authModeOrDefault(string(value)) + if err != nil { + return nil, errors.Wrap(err, errors.Errorf("invalid identity auth mode for %q encountered", nsName).Error()) + + } } if authMode == podIdentity { @@ -292,7 +297,7 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - // Here we check for workload identity if client secret is not provided. + // Here we check for workload identity if client secret is not provided and if not podIdentity. tokenCredential, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{ ClientID: string(clientID), TenantID: string(tenantID), @@ -335,9 +340,14 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string return types.NamespacedName{Namespace: resourceNamespace, Name: credentialFrom} } -func authModeOrDefault(mode string) AuthModeOption { - if mode == string(podIdentity) { - return podIdentity +func authModeOrDefault(mode string) (AuthModeOption, error) { + if mode == "" || strings.EqualFold(mode, string(workloadIdentity)) { + return workloadIdentity, nil } - return workloadIdentity + + if strings.EqualFold(mode, string(podIdentity)) { + return podIdentity, nil + } + + return "", errors.Errorf("authorization mode %q not valid", mode) } From 3b7bdb9f8525b61f2274f2a6494cd81481654ca1 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:32:21 +1200 Subject: [PATCH 07/11] minor refactor --- v2/internal/identity/credential_provider.go | 40 ++++++++++----------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index ad980726beb..bae01359d8b 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -269,35 +269,33 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - var authMode AuthModeOption - var err error if value, hasUsePodIdentity := secret.Data[AuthMode]; hasUsePodIdentity { - authMode, err = authModeOrDefault(string(value)) + authMode, err := authModeOrDefault(string(value)) if err != nil { return nil, errors.Wrap(err, errors.Errorf("invalid identity auth mode for %q encountered", nsName).Error()) } - } - - if authMode == podIdentity { - tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ - ClientOptions: azcore.ClientOptions{}, - ID: azidentity.ClientID(clientID), - }) - if err != nil { - return nil, errors.Wrap(err, errors.Errorf("invalid Managed Identity for %q encountered", nsName).Error()) + if authMode == podIdentity { + tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ + ClientOptions: azcore.ClientOptions{}, + ID: azidentity.ClientID(clientID), + }) + + if err != nil { + return nil, errors.Wrap(err, errors.Errorf("invalid Managed Identity for %q encountered", nsName).Error()) + } + + return &Credential{ + tokenCredential: tokenCredential, + subscriptionID: string(subscriptionID), + credentialFrom: nsName, + secretData: secret.Data, + }, nil } - - return &Credential{ - tokenCredential: tokenCredential, - subscriptionID: string(subscriptionID), - credentialFrom: nsName, - secretData: secret.Data, - }, nil } - // Here we check for workload identity if client secret is not provided and if not podIdentity. + // Default to Workload Identity tokenCredential, err := azidentity.NewWorkloadIdentityCredential(&azidentity.WorkloadIdentityCredentialOptions{ ClientID: string(clientID), TenantID: string(tenantID), @@ -341,7 +339,7 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string } func authModeOrDefault(mode string) (AuthModeOption, error) { - if mode == "" || strings.EqualFold(mode, string(workloadIdentity)) { + if strings.EqualFold(mode, string(workloadIdentity)) { return workloadIdentity, nil } From ae7b436905b5a0a8b6a2134c143ed607b247f171 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:33:37 +1200 Subject: [PATCH 08/11] Refactor naming --- v2/internal/identity/credential_provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index bae01359d8b..5151c71903f 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -269,7 +269,7 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - if value, hasUsePodIdentity := secret.Data[AuthMode]; hasUsePodIdentity { + if value, hasAuthMode := secret.Data[AuthMode]; hasAuthMode { authMode, err := authModeOrDefault(string(value)) if err != nil { return nil, errors.Wrap(err, errors.Errorf("invalid identity auth mode for %q encountered", nsName).Error()) From 8119eb6a66ebe2394314d127c4c6af2ce12d0877 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Tue, 29 Aug 2023 15:35:14 +1200 Subject: [PATCH 09/11] Default to workload identity if auth_mode=='' --- v2/internal/identity/credential_provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 5151c71903f..8865e969b52 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -339,7 +339,7 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string } func authModeOrDefault(mode string) (AuthModeOption, error) { - if strings.EqualFold(mode, string(workloadIdentity)) { + if strings.EqualFold(mode, string(workloadIdentity)) || mode == "" { return workloadIdentity, nil } From 4a7bf9e6cb75c65709ff3097e3b525b04f4f7829 Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:16:26 +1200 Subject: [PATCH 10/11] Export auth mode options constants --- v2/internal/identity/credential_provider.go | 25 ++++++--------------- v2/pkg/common/config/scoped_credentials.go | 15 +++++++++++++ 2 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 v2/pkg/common/config/scoped_credentials.go diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 8865e969b52..1543dc2c198 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -34,17 +34,6 @@ const ( FederatedTokenFilePath = "/var/run/secrets/tokens/azure-identity" ) -type AuthModeOption string - -const ( - podIdentity AuthModeOption = "podidentity" - workloadIdentity AuthModeOption = "workloadidentity" - - // AuthMode enum is used to determine if we're using Pod Identity or Workload Identity - //authentication for namespace and per-resource scoped credentials - AuthMode = "AUTH_MODE" -) - // Credential describes a credential used to connect to Azure type Credential struct { tokenCredential azcore.TokenCredential @@ -269,14 +258,14 @@ func (c *credentialProvider) newCredentialFromSecret(secret *v1.Secret) (*Creden }, nil } - if value, hasAuthMode := secret.Data[AuthMode]; hasAuthMode { + if value, hasAuthMode := secret.Data[config.AuthMode]; hasAuthMode { authMode, err := authModeOrDefault(string(value)) if err != nil { return nil, errors.Wrap(err, errors.Errorf("invalid identity auth mode for %q encountered", nsName).Error()) } - if authMode == podIdentity { + if authMode == config.PodIdentityAuthMode { tokenCredential, err := azidentity.NewManagedIdentityCredential(&azidentity.ManagedIdentityCredentialOptions{ ClientOptions: azcore.ClientOptions{}, ID: azidentity.ClientID(clientID), @@ -338,13 +327,13 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string return types.NamespacedName{Namespace: resourceNamespace, Name: credentialFrom} } -func authModeOrDefault(mode string) (AuthModeOption, error) { - if strings.EqualFold(mode, string(workloadIdentity)) || mode == "" { - return workloadIdentity, nil +func authModeOrDefault(mode string) (config.AuthModeOption, error) { + if strings.EqualFold(mode, string(config.WorkloadIdentityAuthMode)) || mode == "" { + return config.WorkloadIdentityAuthMode, nil } - if strings.EqualFold(mode, string(podIdentity)) { - return podIdentity, nil + if strings.EqualFold(mode, string(config.PodIdentityAuthMode)) { + return config.PodIdentityAuthMode, nil } return "", errors.Errorf("authorization mode %q not valid", mode) diff --git a/v2/pkg/common/config/scoped_credentials.go b/v2/pkg/common/config/scoped_credentials.go new file mode 100644 index 00000000000..54acd3819c0 --- /dev/null +++ b/v2/pkg/common/config/scoped_credentials.go @@ -0,0 +1,15 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package config + +type AuthModeOption string + +const ( + PodIdentityAuthMode AuthModeOption = "podidentity" + WorkloadIdentityAuthMode AuthModeOption = "workloadidentity" + + // AuthMode enum is used to determine if we're using Pod Identity or Workload Identity + //authentication for namespace and per-resource scoped credentials + AuthMode = "AUTH_MODE" +) From 9ee8b18bdd65502bf818e46bcaf9c2a81899d82e Mon Sep 17 00:00:00 2001 From: Harshdeep Singh <38904804+super-harsh@users.noreply.github.com> Date: Wed, 30 Aug 2023 12:12:46 +1200 Subject: [PATCH 11/11] make the authmode check case sensitive --- v2/internal/identity/credential_provider.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/v2/internal/identity/credential_provider.go b/v2/internal/identity/credential_provider.go index 1543dc2c198..aabf3c751cf 100644 --- a/v2/internal/identity/credential_provider.go +++ b/v2/internal/identity/credential_provider.go @@ -328,11 +328,11 @@ func getSecretNameFromAnnotation(credentialFrom string, resourceNamespace string } func authModeOrDefault(mode string) (config.AuthModeOption, error) { - if strings.EqualFold(mode, string(config.WorkloadIdentityAuthMode)) || mode == "" { + if mode == string(config.WorkloadIdentityAuthMode) || mode == "" { return config.WorkloadIdentityAuthMode, nil } - if strings.EqualFold(mode, string(config.PodIdentityAuthMode)) { + if mode == string(config.PodIdentityAuthMode) { return config.PodIdentityAuthMode, nil }