Azure / azure-cli

Azure Command-Line Interface
MIT License
3.92k stars 2.89k forks source link

Calrify how to login with federated token #24756

Open JoHaHu opened 1 year ago

JoHaHu commented 1 year ago

Clarify how to login with federated credential tokens with az cli and note that it applies to both Service Principals and Managed Identities

az login --service-principal -u $CLIENT_ID -t $TENANT --federated-token $TOKEN

Document Details

Do not edit this section. It is required for learn.microsoft.com ➟ GitHub issue linking.

yonzhan commented 1 year ago

@jiasli for awareness

jiasli commented 1 year ago

The help message of --service-principal was provided by federated credential service team. We will refine it once we get more information.

rafagsiqueira commented 1 year ago

Wait, can it be used with managed identities without the proxy sidecar? Genius. It works! Thank you!

esdccs1 commented 4 months ago

So to clarify, If I can normally log on to my Service Principal like az login --service-principal -u <client-id> -p <client-secret> --tenant <tenant>

Is there a way to log on not using client-secret, but fetching the TOKEN somehow?

az login --service-principal -u $CLIENT_ID -t $TENANT --federated-token $TOKEN

how to get $TOKEN?

pachr commented 4 months ago

Federated token value seems to be : api://AzureADTokenExchange if you're using a managed identity and a federated token

fabio-s-franco commented 4 months ago

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

Interactive authentication is needed. Please run: az login

Still unable to login using user assigned identity using workload identity authentication method. The documented way: Log in using a VM's user-assigned managed identity. Client or object ids of the service identity also work. az login --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID

yields:

Failed to connect to MSI. Please make sure MSI is configured correctly. Get Token request returned http error: 400, reason: Bad Request

I verified the environment variables and they are correctly set. The token file is readable. By now just going in circles as specific documantation about az cli login via workload identity with AKS is very scarce or esluding me.

pachr commented 4 months ago

Running az login --service-principal --tenant "${AZURE_TENANT_ID}" --username "${AZURE_CLIENT_ID}" --federated-token "$(cat ${AZURE_FEDERATED_TOKEN_FILE})" works on my side.

I'm using the latest version of az cli, if you used an old version it seems to redirect you in an interactive login.

You can use this docker image: mcr.microsoft.com/azure-cli:latest Or curl the latest version: curl -sL https://aka.ms/InstallAzureCLIDeb

On my side, I was not able to use az login --identity -u <identity_id>, it returns the same error code.

fabio-s-franco commented 4 months ago

Running az login --service-principal --tenant "${AZURE_TENANT_ID}" --username "${AZURE_CLIENT_ID}" --federated-token "$(cat ${AZURE_FEDERATED_TOKEN_FILE})" works on my side.

I'm using the latest version of az cli, if you used an old version it seems to redirect you in an interactive login.

You can use this docker image: mcr.microsoft.com/azure-cli:latest Or curl the latest version: curl -sL https://aka.ms/InstallAzureCLIDeb

On my side, I was not able to use az login --identity -u <identity_id>, it returns the same error code.

Thanks @pachr I finally managed to make it work. I had the Wrong ID set as AZURE_CLIENT_ID. This is all very confusing and with this ID mess Azure identity system is, plus lack of good documentation, makes mistakes like mine are way too easy to make.

pachr commented 4 months ago

Running az login --service-principal --tenant "${AZURE_TENANT_ID}" --username "${AZURE_CLIENT_ID}" --federated-token "$(cat ${AZURE_FEDERATED_TOKEN_FILE})" works on my side. I'm using the latest version of az cli, if you used an old version it seems to redirect you in an interactive login. You can use this docker image: mcr.microsoft.com/azure-cli:latest Or curl the latest version: curl -sL https://aka.ms/InstallAzureCLIDeb On my side, I was not able to use az login --identity -u <identity_id>, it returns the same error code.

Thanks @pachr I finally managed to make it work. I had the Wrong ID set as AZURE_CLIENT_ID. This is all very confusing and with this ID mess Azure identity system is, plus lack of good documentation, makes mistakes like mine are way too easy to make.

@fabio-s-franco yes it's a bit confusing between CLIENT ID, TENANT ID, PRINCIPAL ID, OBJECT ID 😅 glad it works for you.

GabriFedi97 commented 3 months ago

I'm facing the same issue trying to login with MSI from a AKS pod container. Running:

az login --verbose --identity -u /subscriptions/<subscriptionId>/resourcegroups/myRG/providers/Microsoft.ManagedIdentity/userAssignedIdentities/myID

returns

Failed to connect to MSI. Please make sure MSI is configured correctly.
Get Token request returned http error: 400, reason: Bad Request

@fabio-s-franco would you mind sharing what you did to make it works?

fabio-s-franco commented 2 months ago

@GabriFedi97 I am sorry I couldn't get to your question sooner. I have hit this error many times I don't even remember what causes it. Likely many possibilities. Problem of Bad Request is that it doesn't say much. Ideally we could get debug logs for details of the error, but I am unsure I ever got to enable it, or if it is possible to obtain more information.

But my command is different than yours. I never got the command you are using to work. Instead I used the one that authenticates with --service-principal. The example above from pachr. What it does is to use the token mounted on disk, for pods that have the annotation to use workload identity.

The problem I had was about using the correct value for AZURE_CLIENT_ID in the command.

It is all too confusing (which I believe motivated this issue to be created). The error you are seeing is a step that requires to use MSI endpoint to obtain the tokens you should already have. When using workload identity you don't need to obtain the Entra ID/Azure AD token, because that gets projected to the pod. It's the part that "should" make it easier, if only this was explained somewhere.

This token is used to obtain and renew the token that identifies the workload as a service principal (JWT), which then has roles assigned to it, and will be used to access other Azure services which are controlled using RBAC.

So if you're seeing any message about MSI, it's because it's trying to do the step in between, which is not what workload identity mechanism provides. So check these:

1 - Federated Identity is correctly configured, your pod is annotated to use workload identity and the tokens are mounted on disk/volume. You can literally shell into your pod and see them. I don't remember exactly where now.

2 - Make sure the environment variables are set with the right values (tenant id, client id) and your pass the federated token like in the command above. You can't authenticate directly with service principals using managed identities, they are kind of an abstraction on top of them. They still have the associated service principal (which adds to the confusion), but the authentication flow is different if as you had a standalone service principal.

3 - You see that on my post that I have very different error messages. One of them which errors with the MSI endpoint was not suitable to it, so you shouldn't use it. The first one was the correct one, but I had AZURE_CLIENT_ID using the wrong value. I can't even tell you where it is from, I don't remember, where I got it from. If I had to do it again, I would likely have to scavenge it all over again to configure it. TLDR: Use the correct command, if you see MSI error, you're using the wrong command (if you're trying to authenticate managed/user assigned identity).

These 3 pointers will give you enough clues to go through the maze. If you haven't given up already or figured out yourself, or used another solution altogether...

pallavi-vetal commented 2 months ago

Federated token value seems to be : api://AzureADTokenExchange if you're using a managed identity and a federated token

Do we need to specify this as federated token?

pallavi-vetal commented 2 months ago

@GabriFedi97 I am sorry I couldn't get to your question sooner. I have hit this error many times I don't even remember what causes it. Likely many possibilities. Problem of Bad Request is that it doesn't say much. Ideally we could get debug logs for details of the error, but I am unsure I ever got to enable it, or if it is possible to obtain more information.

But my command is different than yours. I never got the command you are using to work. Instead I used the one that authenticates with --service-principal. The example above from pachr. What it does is to use the token mounted on disk, for pods that have the annotation to use workload identity.

The problem I had was about using the correct value for AZURE_CLIENT_ID in the command.

It is all too confusing (which I believe motivated this issue to be created). The error you are seeing is a step that requires to use MSI endpoint to obtain the tokens you should already have. When using workload identity you don't need to obtain the Entra ID/Azure AD token, because that gets projected to the pod. It's the part that "should" make it easier, if only this was explained somewhere.

This token is used to obtain and renew the token that identifies the workload as a service principal (JWT), which then has roles assigned to it, and will be used to access other Azure services which are controlled using RBAC.

So if you're seeing any message about MSI, it's because it's trying to do the step in between, which is not what workload identity mechanism provides. So check these:

1 - Federated Identity is correctly configured, your pod is annotated to use workload identity and the tokens are mounted on disk/volume. You can literally shell into your pod and see them. I don't remember exactly where now.

2 - Make sure the environment variables are set with the right values (tenant id, client id) and your pass the federated token like in the command above. You can't authenticate directly with service principals using managed identities, they are kind of an abstraction on top of them. They still have the associated service principal (which adds to the confusion), but the authentication flow is different if as you had a standalone service principal.

3 - You see that on my post that I have very different error messages. One of them which errors with the MSI endpoint was not suitable to it, so you shouldn't use it. The first one was the correct one, but I had AZURE_CLIENT_ID using the wrong value. I can't even tell you where it is from, I don't remember, where I got it from. If I had to do it again, I would likely have to scavenge it all over again to configure it. TLDR: Use the correct command, if you see MSI error, you're using the wrong command (if you're trying to authenticate managed/user assigned identity).

These 3 pointers will give you enough clues to go through the maze. If you haven't given up already or figured out yourself, or used another solution altogether...

How do we get federated token in azure devops pipeline? Any idea how to extend lifetime of idtoken in azure devops pipeline?

fabio-s-franco commented 1 month ago

How do we get federated token in azure devops pipeline? Any idea how to extend lifetime of idtoken in azure devops pipeline?

Federated tokens are never gotten, they are issued (for example, you can issue one manually and add to your devops pipeline). It depends on the identity provider to manage the lifetime of the token. Maybe what you want to do would benefit more from using MSI instead.

There is a github integration example, which may be relevant to you to see if it is appropriate to your use case: https://learn.microsoft.com/en-us/azure/developer/github/connect-from-azure?tabs=azure-portal%2Cwindows

AisseMTT commented 1 month ago

@pallavi-vetal Did you get it working on your pipelines?