Azure / azure-sdk-for-rust

This repository is for active development of the *unofficial* Azure SDK for Rust. This repository is *not* supported by the Azure SDK team.
MIT License
701 stars 243 forks source link

add SpecificAzureCredential #1503

Closed cataggar closed 9 months ago

cataggar commented 10 months ago

This is a proposed design to be able to specify the type of credential from an environment variable such as AZURE_CREDENTIAL_KIND. If the environment variable was set it would pick the desired credential. The mapping from String to TokenCredential would be like:

The SpecificAzureCredential could then be added as the first option in DefaultAzureCredential.

The proposed implementation is #1532. It removes spaces and makes lowercase before matchingruns .replace(' ', "").to_lowercase().as_str(). This allows AZURE_CREDENTIAL_KIND to be set to Azure CLI or Virtual Machine as examples.

cataggar commented 9 months ago

Here are the credentials used by the Azure SDK for .NET based on

mindmap
  root((.NET DefaultAzureCredential))
    1 Environment
      1a Client Secret
      1b Client Certificate
      1c Username Password
    2 Workload Identity
    3 Managed Identity
      3a Service Fabric
      3b App Service
      3c Cloud Shell
      3d Azure Arc
      3e Virtual Machine
    4 Shared Token Cache
    5 Visual Studio
    6 Visual Studio Code
    7 Azure CLI
    8 Azure PowerShell
    9 Azure Developer CLI
    10 Interactive Browser
demoray commented 9 months ago

As a total aside: TIL GitHub supports mindmaps!

cataggar commented 9 months ago

Here are the credentials listed above for the Azure SDK for Rust.

mindmap
  root((Rust DefaultAzureCredential))
    1 Environment
      1a Client Secret
      1b Client Certificate
    2 Workload Identity
    3 Managed Identity
      3a Service Fabric
      3b App Service
      3c Cloud Shell
      3d Azure Arc
      3e Virtual Machine
    4 Azure CLI
cataggar commented 9 months ago

This design proposal is that a new SpecificAzureCredential is added to DefaultAzureCredential. It is the first source credential and the only one used if AZURE_CREDENTIAL_KIND is set. It will create one of the other credentials by name or error.

mindmap
  root((Rust DefaultAzureCredential))
    (1 SpecificAzureCredential AZURE_CREDENTIAL_KIND)
    2 Environment
      2a Client Secret
      2b Client Certificate
    3 Workload Identity
    4 Managed Identity
      4a Service Fabric
      4b App Service
      4c Cloud Shell
      4d Azure Arc
      4e Virtual Machine
    5 Azure CLI

The current behavior of DefaultAzureCredential remains the same when AZURE_CREDENTIAL_KIND is not set. Like other sources for DefaultAzureCredential, there is a compile-time option to disable SpecificAzureCredential.

This change simplifies many use cases. Especially when deploying to any of the environments covered by Workload Identity or any of the Managed Identities.

cataggar commented 9 months ago

In #1532, SpecificAzureCredential was not added to DefaultAzureCredential as proposed. However, a factory method was added that allows creating one or the other. A SpecificAzureCredential is created if the AZURE_CREDENTIAL_KIND environment variable is set.

let credential = azure_identity::create_credential()?;
cataggar commented 9 months ago

Here are the credentials for the Azure Identity client library for C++. https://github.com/Azure/azure-sdk-for-cpp/blob/main/sdk/identity/azure-identity

mindmap
  root((C++ DefaultAzureCredential))
    1 Environment
      1a Client Secret
      1b Client Certificate
    2 Workload Identity
    3 Azure CLI
    4 Managed Identity
      4a App Service
      4b Cloud Shell
      4c Azure Arc
      4d Virtual Machine

One difference is that they check the Azure CLI before Managed Identity.

heaths commented 9 months ago

One difference is that they (C++) check the Azure CLI before Managed Identity.

@joshfree is that expected?

ahsonkhan commented 8 months ago

@heaths that is not expected. The C++ order in the DAC is different currently because ManagedIdentity doesn't fail fast (due to the lack of a quick IMDS probing that other languages do). So, it ends up being at the end, and AzureCli is before it.

We plan to change that, to be consistent with the rest of the languages once this issue has been tackled: https://github.com/Azure/azure-sdk-for-cpp/issues/4952 https://github.com/Azure/azure-sdk-for-cpp/issues/5279