Azure / azure-sdk-for-go

This repository is for active development of the Azure SDK for Go. For consumers of the SDK we recommend visiting our public developer docs at:
https://docs.microsoft.com/azure/developer/go/
MIT License
1.62k stars 826 forks source link

Token caching for AzureCLICredential #23533

Open mateuszlitwin opened 1 week ago

mateuszlitwin commented 1 week ago

Feature Request

Based on https://github.com/Azure/azure-sdk-for-go/blob/main/sdk/azidentity/TOKEN_CACHING.MD#credentials-supporting-token-caching caching is not implemented for AzureCLICredential. I use az login extensively and would like to reuse tokens when using Go cli. Currently this results in a poor performance.

github-actions[bot] commented 1 week ago

Thank you for your feedback. Tagging and routing to the team member best able to assist.

chlowell commented 1 week ago

This is by design. We want credential types invoking external tools (AzureCLICredential, AzureDeveloperCLICredential) to always authenticate the user logged in to the tool, which can change at any time. Caching tokens in the credential would enable behavior that's difficult to understand and can cause hard to debug failures. For example:

  1. az login user A
  2. credential acquires a Storage token
  3. az login user B
  4. credential acquires a Key Vault token

If the credential caches those tokens, then the user authenticated by the credential depends on the resource being accessed, and the application may see unexpected authorization failures or act with unexpected privileges.

So, AzureCLICredential.GetToken() always runs the CLI to get a token. This makes the credential less performant but we accept that tradeoff because

However, Azure SDK clients do cache tokens, regardless of the credential type, so e.g. a Key Vault client doesn't call AzureCLICredential.GetToken() every time you call one of its methods. Reusing client instances therefore reduces the frequency of authentication in your app.

Another way to get a similar workflow with better performance is to use AzureDeveloperCLICredential instead. azd runs much faster than az.

github-actions[bot] commented 1 week ago

Hi @mateuszlitwin. Thank you for opening this issue and giving us the opportunity to assist. We believe that this has been addressed. If you feel that further discussion is needed, please add a comment with the text "/unresolve" to remove the "issue-addressed" label and continue the conversation.

mateuszlitwin commented 1 week ago

What type of tokens would you recommend for usage in Go-based CLIs? AzureCLICredential performance is pretty bad, it adds >0.5s latency, I was hoping with better caching it can be avoided for repeated calls.

chlowell commented 2 days ago

For a CLI authenticating users, I recommend InteractiveBrowserCredential and DeviceCodeCredential. You can enable persistent caching for these credentials so users don't have to log in every time they run your CLI. InteractiveBrowserCredential is a reasonable default but generally doesn't work in remote or headless environments such as SSH sessions because it tries to open a web browser and redirect to localhost. DeviceCodeCredential is designed for those environments. You could try to automatically fall back to device code auth when the browser approach fails, however I'd recommend adding a flag like --device-code so users can always work around problems by forcing your CLI to use the simpler credential.