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
674 stars 230 forks source link

Cannot use a User Assigned Managed Identity with azure_identity 0.20.0 #1659

Open johnbatty opened 1 month ago

johnbatty commented 1 month ago

Using azure_identity prior to 0.20.0 I was able to use specific User Assigned Managed Identity credentials like this:

ImdsManagedIdentityCredential::default()
                    .with_object_id(&managed_identity_object_id)

For 0.20.0 there was an overhaul of how credentials are created, and it no longer appears possible to create an ImdsManagedIdentity with an object_id.

This is a major issue for my project (and I imagine others) - we rely on User Assigned Managed Identities so can't upgrade azure_identity without a fix to restore this capability.

I do note there is an outstanding issue for creating a ManagedIdentityCredential: https://github.com/Azure/azure-sdk-for-rust/issues/1536

I'm happy to make a fix, but need to agree what the API should look like.

The previous method of creating an ImdsManagedIdentityCredential and then calling one of the other methods to set a value felt a bit hacky. Might be simpler to expose the above ImdsId enum in the public API, and then allow it to be passed in a new constructor. Although possibly a bit odd passing in ImdsId to a ManagedIdentityCredential (without the Imds prefix). Could rename ImdsId in the API, perhaps:

ManagedIdentityCredential::new(id: ImdsId, options: impl Into<TokenCredentialOptions>)

For comparison, the .NET SDK ManagedIdentityCredential has multiple overloaded constructors for creating the different variants:

Any thoughts/suggestions appreciated.

cataggar commented 1 month ago

You are on the right track @johnbatty. Please see this discussion for context.

cataggar commented 1 month ago

I made it public again in #1660, but it should probably be private long term. Are you looking for VirtualMachineManagedIdenityCredential, but with a way to specify the user assigned managed identity?

johnbatty commented 1 month ago

@cataggar

I made it public again in https://github.com/Azure/azure-sdk-for-rust/pull/1660, but it should probably be private long term.

Thank you!

Are you looking for VirtualMachineManagedIdenityCredential, but with a way to specify the user assigned managed identity?

Yes

johnbatty commented 1 month ago

@cataggar

Perhaps we could just update the VirtualMachineManagedIdentityCredential constructor to take an additional id parameter, which would then allow it to be used for either System Assigned or User Assigned ids?

Current:

    pub fn new(options: impl Into<TokenCredentialOptions>) -> Self {
        let endpoint = Url::parse(ENDPOINT).unwrap(); // valid url constant
        Self {
            credential: ImdsManagedIdentityCredential::new(
                options,
                endpoint,
                API_VERSION,
                SECRET_HEADER,
                SECRET_ENV,
                ImdsId::SystemAssigned,
            ),
        }
    }

New:

    pub fn new(id: ImdsId, options: impl Into<TokenCredentialOptions>) -> Self {
        let endpoint = Url::parse(ENDPOINT).unwrap(); // valid url constant
        Self {
            credential: ImdsManagedIdentityCredential::new(
                options,
                endpoint,
                API_VERSION,
                SECRET_HEADER,
                SECRET_ENV,
                id,
            ),
        }
    }
cry-inc commented 4 weeks ago

I have a similar issue and also had to revert back to 0.19 because 0.20 did not allow me to create a managed identity credentials with a customized client ID.

My application runs normally in a Azure Batch VM with a identity specified from an ENV variable, but I also need to be able to run it locally with my Azure CLI credentials.

Right now I use code that looks like this:

let credentials: Arc<dyn TokenCredential> = if let Some(client_id) = &args.batch_task_identity {
    Arc::new(ImdsManagedIdentityCredential::default().with_client_id(client_id))
} else {
    Arc::new(DefaultAzureCredential::default())
};

Maybe it would be possible to specify custom IDs for managed identities by extending the TokenCredentialOptions struct introduced in 0.20?

If this struct would include options for the customized client IDs for the managed identity credentials, the code could be simplified to something like that:

let mut options = TokenCredentialOptions::default();
options.set_managed_identity_client_id(args.batch_task_identity);
let credentials = Arc::new(DefaultAzureCredential::create(options)?);