Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

az login support for Azure AD workload identity with Azure Kubernetes Service #26858

Open
arsnyder16 opened this issue Jul 10, 2023 · 16 comments
Assignees
Labels
Account az login/account Auto-Assign Auto assign by bot Azure CLI Team The command of the issue is owned by Azure CLI team customer-reported Issues that are reported by GitHub users external to the Azure organization. feature-request
Milestone

Comments

@arsnyder16
Copy link

Related command
az login

Is your feature request related to a problem? Please describe.
Currently if using workload identity and azure cli, az login must be specifically configured for login

Describe the solution you'd like
similar to az login --identity, maybe something like az login --workflow-identity
Describe alternatives you've considered
You can work around it currently using
az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID

Additional context
For the client libraries a specific class is available WorkloadIdentityCredential

More generally it would be nice if az login had a way to use something similar to DefaultAzureCredential which would allow scripts to be more portable depending on execution context

@ghost ghost added customer-reported Issues that are reported by GitHub users external to the Azure organization. Auto-Assign Auto assign by bot Account az login/account labels Jul 10, 2023
@yonzhan
Copy link
Collaborator

yonzhan commented Jul 10, 2023

Thank you for opening this issue, we will look into it.

@ghost ghost assigned jiasli Jul 10, 2023
@ghost ghost added this to the Backlog milestone Jul 10, 2023
@ghost ghost added Azure CLI Team The command of the issue is owned by Azure CLI team question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jul 10, 2023
@RickardTaran
Copy link

Same issue, thanks for posting a workaround! Hope to see this fixed

@yonzhan yonzhan added feature-request and removed question The issue doesn't require a change to the product in order to be resolved. Most issues start as that labels Jul 11, 2023
@jiasli
Copy link
Member

jiasli commented Jul 12, 2023

A similar feature request has been raised for Azure PowerShell: Azure/azure-powershell#22213

Supporting workload identity requires reading from these environment variables:

  • AZURE_AUTHORITY_HOST
  • AZURE_CLIENT_ID
  • AZURE_TENANT_ID
  • AZURE_FEDERATED_TOKEN_FILE

(Documented at https://azure.github.io/azure-workload-identity/docs/quick-start.html?highlight=AZURE_FEDERATED_TOKEN_FILE#7-deploy-workload)

The AKS document https://learn.microsoft.com/en-us/azure/aks/workload-identity-overview#microsoft-authentication-library-msal provides samples that directly use MSAL for workload identity authentication. For example, the MSAL Python sample reads values from environment variables first:

https://github.com/Azure/azure-workload-identity/blob/a5fc57dd72e5fe2d85a21072d47eb3aa2b316407/examples/msal-python/main.py#L9-L12

    azure_client_id = os.getenv('AZURE_CLIENT_ID', '')
    azure_tenant_id = os.getenv('AZURE_TENANT_ID', '')
    azure_authority_host = os.getenv('AZURE_AUTHORITY_HOST', '')
    azure_federated_token_file = os.getenv('AZURE_FEDERATED_TOKEN_FILE', '')

Then it uses the same mechanism as Azure CLI - creating ConfidentialClientApplication instance with client_assertion:

https://github.com/Azure/azure-workload-identity/blob/a5fc57dd72e5fe2d85a21072d47eb3aa2b316407/examples/msal-python/token_credential.py#L14-L20

        self.app = ConfidentialClientApplication(
            azure_client_id,
            client_credential={
                'client_assertion': f.read().decode("utf-8")
            },
            authority="{}{}".format(azure_authority_host, azure_tenant_id)
        )

Azure CLI's code:

# client_assertion
client_assertion = getattr(service_principal_auth, _CLIENT_ASSERTION, None)
if client_assertion:
client_credential = {'client_assertion': client_assertion}
super().__init__(service_principal_auth.client_id, client_credential=client_credential, **kwargs)

The workaround provided in the issue description is the right path. In order for Azure CLI to natively support workload identity, it has to read those environment variables as the workaround does. But, we still need to work with MSAL team to decide whether this logic should be done by Azure CLI or MSAL.

A prerequisite is to support environment credentials first: #10241

@wba-josh-hetland
Copy link

I'm interested in this as well, for the use case i am interested in, it would be to host azure devops agents in a k8s environment and use the workload identity for the service connection vs having to script this out and tightly couple the pipeline tasks to its hosting environment

@OliverKleinBST
Copy link

Same issue, thanks for posting a workaround! Hope to see this fixed

@rikhil-s
Copy link

Interested in this too. Would be great to have a native implementation of this in Azure CLI.

@Veljen
Copy link

Veljen commented Mar 13, 2024

az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID

how to get this federated token using the azure devops pipeline script task ? workload identity works fine with kubernetes , kubectl or helm task in the azure devops. But its not working in the azure cli task.

@PIrojahPerbak
Copy link

az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID

AZURE_FEDERATED_TOKEN_FILE - this env var is injected into the pod if you enable workload identity

@Veljen
Copy link

Veljen commented Jun 21, 2024

Will this work in azure devops - AzureCLI@2 task ?

@PIrojahPerbak
Copy link

PIrojahPerbak commented Jun 21, 2024

Will this work in azure devops - AzureCLI@2 task ?

Depends on your configuration - if you have followed the instructions on the workload identity page then it should work: https://azure.github.io/azure-workload-identity/docs/quick-start.html?highlight=AZURE_FEDERATED_TOKEN_FILE#7-deploy-workload.

If you dont mind me asking have you configured workload identity in the agent? Otherwise you might have to enable an oidc auth task in the pipeline

@Veljen
Copy link

Veljen commented Jun 21, 2024

My scenario is different here, I have configured workload identity in azure devops service connection.

this kubernetes plugin works fine using this aksinfralab service connection and can deploy the resource in k8s. (this service populating the federated token file in the agentpool)

# - task: Kubernetes@1
#   displayName: 'kubectl apply'
#   inputs:
#     azureSubscriptionEndpoint: 'aksinfralab'
#     azureResourceGroup: 'aks-pipeline'
#     kubernetesCluster: 'aks-lab-pipeline'
#     connectionType: 'Azure Resource Manager'
#     command: 'get'
#     arguments: 'pods'

when comes to azureCli task. I want to use this below. using this service connection I don't see the environment variables populated for the AZURE_FEDERATED_TOKEN_FILE in the agentpool

- task: AzureCLI@2
  displayName: 'Kubeconfig generator'
  inputs:
    azureSubscription: 'aksinfralab'
    scriptType: 'bash'
    addSpnToEnvironment: true
    scriptLocation: 'inlineScript'
    inlineScript: |
      az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID
      az aks get-credentials --resource-group aks-pipeline --name aks-lab-pipeline -f $(Build.ArtifactStagingDirectory)/kubeconfig-dev
      kubelogin convert-kubeconfig -l workloadidentity --kubeconfig  $(Build.ArtifactStagingDirectory)/kubeconfig-dev


This is AD enabled cluster hence we need to use the kubelogin with any service principal. #agentpool is vm.

@guidojw
Copy link

guidojw commented Aug 7, 2024

How does this work with the azureSubscription parameter? AKS workload identity will already inject it right, is inputting the subscription in the task not double?

@colinrippeyfinarne
Copy link

For anyone interested in logging into the az cli using their own self generated tokens I've written up a series of blog posts on how to get the OIDC documents setup, provision associated azure resources, then login to az cli using the signed client assertion: https://finarne.wordpress.com/2024/07/25/acquire-an-entra-id-token-using-federated-credentials-part-1-oidc-discovery-documents/

@eminwux
Copy link

eminwux commented Aug 25, 2024

+1

@cveld
Copy link

cveld commented Sep 17, 2024

I was looking for an easy way to leverage a service account and to get a token for the managed identity. These two lines served my purpose. Maybe it provides help to others as well:

    $result = kubectl create token $SERVICEACCOUNT --namespace $NAMESPACE --audience api://AzureADTokenExchange
    az login --federated-token $result --service-principal -u $CLIENT_ID -t $TENANT_ID

The kubernetes cluster must have the OIDC token provider enabled. Interestingly the workload identity feature of AKS can be left disabled.

@maulik13
Copy link

maulik13 commented Oct 10, 2024

I tried using the following but it does not work due to mismatch in audience. The audience in the token pointed by the AZURE_FEDERATED_TOKEN_FILE contains oidc/cluster urls which throws error during the login process.

az login --federated-token "$(cat $AZURE_FEDERATED_TOKEN_FILE)" --service-principal -u $AZURE_CLIENT_ID -t $AZURE_TENANT_ID

The solution provided by @cveld works where it is getting token specifically for audience api://AzureADTokenExchange.

However, I cannot run kubectl create token inside the cluster without creating a new rbac for the respective service account. So this is really inconvenient.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Account az login/account Auto-Assign Auto assign by bot Azure CLI Team The command of the issue is owned by Azure CLI team customer-reported Issues that are reported by GitHub users external to the Azure organization. feature-request
Projects
None yet
Development

No branches or pull requests