diff --git a/deploy/templates/_helpers.tpl b/deploy/templates/_helpers.tpl index 0f40c4e..088d547 100644 --- a/deploy/templates/_helpers.tpl +++ b/deploy/templates/_helpers.tpl @@ -49,7 +49,7 @@ Selector labels app.kubernetes.io/name: {{ include "az-appconfig-k8s-provider.name" . }} app.kubernetes.io/instance: {{ .Release.Name }} control-plane: controller-manager -{{- if eq .Values.workloadIdentity.enabled true }} +{{- if and (.Values.workloadIdentity.enabled) (not .Values.workloadIdentity.disableGlobalServiceAccount) }} azure.workload.identity/use: "true" {{- end }} {{- end }} diff --git a/deploy/templates/clusterrole.yaml b/deploy/templates/clusterrole.yaml index 23f259a..64bffcb 100644 --- a/deploy/templates/clusterrole.yaml +++ b/deploy/templates/clusterrole.yaml @@ -53,7 +53,7 @@ rules: - patch - update - watch -{{- if eq .Values.workloadIdentity.enabled true }} +{{- if .Values.workloadIdentity.enabled }} - apiGroups: - "" resources: diff --git a/deploy/templates/serviceaccount.yaml b/deploy/templates/serviceaccount.yaml index cf835e9..c036964 100644 --- a/deploy/templates/serviceaccount.yaml +++ b/deploy/templates/serviceaccount.yaml @@ -9,7 +9,7 @@ metadata: {{- if .Values.serviceAccount.annotations }} {{ toYaml .Values.serviceAccount.annotations . | nindent 4 }} {{- end }} - {{- if eq .Values.workloadIdentity.enabled true }} + {{- if and (.Values.workloadIdentity.enabled) (not .Values.workloadIdentity.disableGlobalServiceAccount) }} azure.workload.identity/client-id: "" {{- end }} {{- end }} \ No newline at end of file diff --git a/internal/controller/utils.go b/internal/controller/utils.go index 3459003..104f774 100644 --- a/internal/controller/utils.go +++ b/internal/controller/utils.go @@ -248,14 +248,14 @@ func verifyWorkloadIdentityParameters(workloadIdentity *acpv1.WorkloadIdentityPa if workloadIdentity.ManagedIdentityClientId != nil { if strings.EqualFold(os.Getenv(WorkloadIdentityDisableGlobalServiceAccount), "true") { - return loader.NewArgumentError("auth.workloadIdentity.managedIdentityClientId", fmt.Errorf("managedIdentityClientId is not allowed since only custom service account is allowed")) + return loader.NewArgumentError("auth.workloadIdentity.managedIdentityClientId", fmt.Errorf("'managedIdentityClientId' is not allowed since global service account is disabled")) } authCount++ } if workloadIdentity.ManagedIdentityClientIdReference != nil { if strings.EqualFold(os.Getenv(WorkloadIdentityDisableGlobalServiceAccount), "true") { - return loader.NewArgumentError("auth.workloadIdentity.managedIdentityClientIdReference", fmt.Errorf("managedIdentityClientIdReference is not allowed since only custom service account is allowed")) + return loader.NewArgumentError("auth.workloadIdentity.managedIdentityClientIdReference", fmt.Errorf("'managedIdentityClientIdReference' is not allowed since global service account is disabled")) } authCount++ } @@ -265,11 +265,11 @@ func verifyWorkloadIdentityParameters(workloadIdentity *acpv1.WorkloadIdentityPa } if authCount == 0 { - return loader.NewArgumentError("auth.workloadIdentity", fmt.Errorf("one of managedIdentityClientId, managedIdentityClientIdReference and serviceAccountName is required")) + return loader.NewArgumentError("auth.workloadIdentity", fmt.Errorf("setting one of 'managedIdentityClientId', 'managedIdentityClientIdReference' or 'serviceAccountName' field is required")) } if authCount > 1 { - return loader.NewArgumentError("auth.workloadIdentity", fmt.Errorf("only one of managedIdentityClientId, managedIdentityClientIdReference and serviceAccountName is allowed")) + return loader.NewArgumentError("auth.workloadIdentity", fmt.Errorf("setting only one of 'managedIdentityClientId', 'managedIdentityClientIdReference' or 'serviceAccountName' field is allowed")) } if workloadIdentity.ManagedIdentityClientId != nil { diff --git a/internal/loader/configuration_client_manager.go b/internal/loader/configuration_client_manager.go index c2e23a9..dadc7a1 100644 --- a/internal/loader/configuration_client_manager.go +++ b/internal/loader/configuration_client_manager.go @@ -75,7 +75,7 @@ const ( MinBackoffDuration time.Duration = time.Second * 30 JitterRatio float64 = 0.25 SafeShiftLimit int = 63 - AzureDefaultAudience string = "api://AzureADTokenExchange" + ApiTokenExchangeAudience string = "api://AzureADTokenExchange" AnnotationClientID string = "azure.workload.identity/client-id" AnnotationTenantID string = "azure.workload.identity/tenant-id" ) @@ -493,17 +493,18 @@ func newClientAssertionCredential(ctx context.Context, serviceAccountName string return nil, err } - tenantId, ok := os.LookupEnv(strings.ToUpper(AzureTenantId)) - if !ok { - return nil, fmt.Errorf("no tenant ID specified. Check pod configuration or set TenantID in the options") - } - if _, ok := serviceAccountObj.Annotations[AnnotationClientID]; !ok { - return nil, fmt.Errorf("service account %s/%s does not have annotation %s", serviceAccountNamespace, serviceAccountName, AnnotationClientID) + return nil, fmt.Errorf("annotation '%s' of service account %s/%s is required", AnnotationClientID, serviceAccountNamespace, serviceAccountName) } + tenantId := "" + if _, ok := serviceAccountObj.Annotations[AnnotationTenantID]; ok { tenantId = serviceAccountObj.Annotations[AnnotationTenantID] + } else if _, ok := os.LookupEnv(strings.ToUpper(AzureTenantId)); ok { + tenantId = os.Getenv(strings.ToUpper(AzureTenantId)) + } else { + return nil, fmt.Errorf("annotation '%s' of service account %s/%s is required since using global service account for workload identity is disabled", AnnotationTenantID, serviceAccountNamespace, serviceAccountName) } getAssertionFunc := newGetAssertionFunc(serviceAccountNamespace, serviceAccountName) @@ -517,7 +518,7 @@ func newClientAssertionCredential(ctx context.Context, serviceAccountName string } func newGetAssertionFunc(serviceAccountNamespace string, serviceAccountName string) func(ctx context.Context) (string, error) { - audiences := []string{AzureDefaultAudience} + audiences := []string{ApiTokenExchangeAudience} return func(ctx context.Context) (string, error) { cfg, err := ctrlcfg.GetConfig()