Skip to content

Migration path due to removal of create_default_credential in Azure identity SDK #4541

@ChihweiLHBird

Description

@ChihweiLHBird

So Microsoft removed create_default_credential and ChainedTokenCredential (CTC), #2283

What's the recommended migration way for Azure authentication support in framework like spin? Do we now have to build entire CTC by ourselves?
https://github.com/spinframework/spin/blob/ce2c88ac352a7b8b4a8a3f42efecce3acb8008b7/crates/key-value-azure/src/store.rs#L90

If spin goes with DeveloperToolsCredential only, it will not be easy for users to use those multiple kinds of managed credentials.

I personally recommend adding CTC back, if developer experience is still a thing to be considered.

Does Microsoft really want me to build and maintain something like this below? What if Microsoft decides to make further changes to its authentication stuff?

use azure_core::credentials::{Secret, SecretBytes, TokenCredential};
use azure_identity::{
    ClientSecretCredential, DeveloperToolsCredential, ManagedIdentityCredential,
    WorkloadIdentityCredential,
};
#[cfg(feature = "client_certificate")]
use azure_identity::{
    ClientCertificateCredential, ClientCertificateCredentialOptions,
};

const COSMOS_AAD_SCOPE: &str = "https://cosmos.azure.com/.default";

async fn ambient_credential() -> Result<Arc<dyn TokenCredential>, Error> {
    let scopes = [COSMOS_AAD_SCOPE];

    if let Ok(c) = WorkloadIdentityCredential::new(None) {
        if c.get_token(&scopes, None).await.is_ok() {
            return Ok(c);
        }
    }

    if let (Ok(tenant_id), Ok(client_id), Ok(secret)) = (
        std::env::var("AZURE_TENANT_ID"),
        std::env::var("AZURE_CLIENT_ID"),
        std::env::var("AZURE_CLIENT_SECRET"),
    ) {
        if let Ok(c) = ClientSecretCredential::new(
            &tenant_id,
            client_id,
            Secret::from(secret),
            None,
        ) {
            if c.get_token(&scopes, None).await.is_ok() {
                return Ok(c);
            }
        }
    }

    #[cfg(feature = "client_certificate")]
    if std::env::var_os("AZURE_CLIENT_SECRET").is_none() {
        if let (Ok(tenant_id), Ok(client_id), Ok(path)) = (
            std::env::var("AZURE_TENANT_ID"),
            std::env::var("AZURE_CLIENT_ID"),
            std::env::var("AZURE_CLIENT_CERTIFICATE_PATH"),
        ) {
            if let Ok(bytes) = std::fs::read(&path) {
                let mut options = ClientCertificateCredentialOptions::default();
                if let Ok(password) = std::env::var("AZURE_CLIENT_CERTIFICATE_PASSWORD") {
                    options.password = Some(Secret::from(password));
                }
                if let Ok(c) = ClientCertificateCredential::new(
                    tenant_id,
                    client_id,
                    SecretBytes::from(bytes),
                    Some(options),
                ) {
                    if c.get_token(&scopes, None).await.is_ok() {
                        return Ok(c);
                    }
                }
            }
        }
    }

    if let Ok(c) = ManagedIdentityCredential::new(None) {
        if c.get_token(&scopes, None).await.is_ok() {
            return Ok(c);
        }
    }

    if let Ok(c) = DeveloperToolsCredential::new(None) {
        if c.get_token(&scopes, None).await.is_ok() {
            return Ok(c);
        }
    }

    Err(Error::Other(
        "no ambient Azure credential could obtain a Cosmos DB token".into(),
    ))
}

Metadata

Metadata

Assignees

Labels

Azure.IdentityThe azure_identity crateClientThis issue points to a problem in the data-plane of the library.customer-reportedIssues that are reported by GitHub users external to the Azure organization.issue-addressedWorkflow: The Azure SDK team believes it to be addressed and ready to close.

Type

No type
No fields configured for issues without a type.

Projects

Status
Untriaged
Status
Untriaged

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions