Azure-functions-host: Storage Binding using Managed Identity instead of ConnectionString?

Created on 28 Jul 2020  路  23Comments  路  Source: Azure/azure-functions-host

Is your question related to a specific version? If so, please specify:

What language does your question apply to? (e.g. C#, JavaScript, Java, All)

All

Question

Hi! Is there a possibility to use a blob storage binding against a blob storage using the Managed Service Identity of the Azure Function? I'm checking the documentation and there are only examples of defining the binding using the Storage Account Connection String....

Thanks

Most helpful comment

Yep the work is in progress and should be available for use in a couple of months (hopefully we'll be able to communicate more precisely about the expected GA date once we have a preview of the full end-to-end available).

All 23 comments

Not sure if this is supported for Storage Accounts in general.
Your functions app does get Managed Service Identity, but Storage Accounts does not know how to accept and verify connections based on it I think.

Usually resources that support this has a Settings > Access Policies blade in portal which lets you configure which MSI is allowed to do what, for example, key vault resources have this but storage accounts dont.

Alternatively you can certainly create a connection string based on a SAS that would expire at a particular time or only has certain access rights. If you use the secondary key for this SAS, rotating that key can invalidate all SAS tokens signed by that key. I understand this is not the same as MSI, but this is the closest I can think of.

Keen to know if the above is wrong.

@madushans it is supported for Storage Accounts, I have Managed Identity of my Function App activated, and I gave it "Storage Blob Data Contributor" role in the Storage Account.

You can configure RBAC for your Storage Account following this article if you want: https://docs.microsoft.com/en-us/azure/storage/common/storage-auth-aad-rbac-portal

I don't want to use a connection string with a SAS, I want to be passwordless if possible, as it is easier to maintain and I can benefit from RBAC capabilities.

@dedreira Sorry, didn't knew about that.

I dont think Storage in Functions natively support it.

i.e Key Vault SDK allows the connection string to be RunAs=App; to use this feature but storage doesn't.

@madushans thanks a lot for your answer...unfortunately this is not what I was looking for.

As I wrote when I opened the Issue/Question, I was trying to use a "Storage Binding" against a Storage Account using a Managed Identity instead of a Connection String.

As you probably know, Azure Function Bindings provide a way of connecting with other Azure resources without the need of writing the high amount of code needed in other scenarios (App Service, for example).

https://docs.microsoft.com/en-us/azure/azure-functions/functions-triggers-bindings

So, I'm going to explain what am I trying to do,to clarify the purpose of this Issue/Question:

I'm writing a Function in python that's going to "listen" to a container in a Storage Account using a Storage Binding. When a new file is inserted in this container, I want the Function to be fired automatically.

The Azure Function Bindings Documentation says that to configure the input Storage trigger you need to specify a bunch of data, and one of these parameters is the Connection String of the Storage Account.:

https://docs.microsoft.com/en-us/azure/azure-functions/functions-bindings-storage-blob-trigger?tabs=csharp#configuration

(Please don't mind I have posted the C# version of the docs, as it's similar in python)

The point here is that I want to use the Managed Identity of the Function to configure the trigger and connect with the Storage Account, and get rid of the Storage Account connection string.

I'm using Azure DevOps Pipelines CI/CD capabilities to package and deploy the function into several environments, and I'm not comfortable with dealing with connection strings in my pipelines (also I'm not comfortable with saving these connection strings in the App Settings of the Function) because I don't want to (depend of / expose) the Storage Access Keys so, I think it would be great to be able to use a MSI to configure the Storage Binding.

As you have said in your comment, Key Vault SDK allows to use this feature, as I've read, also Event Hubs SDK. but sadly, this is not available for Storage Account SDK.

I would love if someone of the Azure Functions team or the Storage Account SDK Team could read this Issue and tell us their thoughts about this feature. 馃槃

I think either @jeffhollan or @mattchenderson have discussed using Managed Identities with different bindings. I believe we first need support from the underlying SDK -- but maybe it's supported in newer versions of the Storage SDK? https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/identity/Azure.Identity#authenticating-a-service-principal-with-a-client-secret...

@brettsam I know that it's possible to connect with a Storage Account from the Azure.Storage SDK using Managed Identities in C# and in python (as I've done it before with C# and now with python 馃槃) but the point here is that the storage binding to connect with the storage account only accepts a storage connection String. It would be great to have the possibility to choose the connection type:

  • ConnectionString (to continue as it has been all this time)
  • Credentials (To enable Service Principal / MSI Authentication)

@jeffhollan , @mattchenderson , @brettsam what do you think?

Agreed that this is a goal, and we're in the process of working with the Azure SDK folks around this. I don't have an ETA yet.

Moved this to backlog until we have a design and plan. Then we'll move it to a proper milestone.

Running Azure functions in docker containers inside of Kubernetes with Pod Identity (managed identity) is one place where this would be helpful. Right now I can configure Keda/autoscalar to use pod ID but I still have to managed the connection string for the binding itself which is quite unfortunate. It would definitely be nice for queue storage bindings to support managed ID so that all we need is account name and queue.

Any progress / indication when this might be available?

It would indeed be a nice feature to have, because currently all my function code is using managed identity except the bindings, which is a little bit unfortunate. So it would be nice if you good just specify https://mystorageacount.blob.core.windows.net/ as the connection string and Azure functions which create a client using managed identity.

An "inbetween" solution would be, if the binding is not only able to read the connection string from the configuration but also from a configured key-vault. That way the connection string is stored more secured and you have a central place for managing the connection strings.

I would also greatly appreciate this (in all bindings)!
@JohanKlijn This is already possible in app settings - https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

Checking in to see if any progress has been made on this one. It would be nice to be able use Managed Identity for the function queue trigger, connection property. Right now, I just pull it from the config.

I would also greatly appreciate this (in all bindings)!
@JohanKlijn This is already possible in app settings - https://docs.microsoft.com/en-us/azure/app-service/app-service-key-vault-references

I didn't know the vault-references, so thanks for the info!

any update on this @brettsam ?

This work has been moved to the Azure SDK, which has released 5.0.0-beta.1 that looks to have this functionality. You can see those release notes here: https://github.com/Azure/azure-sdk-for-net/blob/master/sdk/storage/Microsoft.Azure.WebJobs.Extensions.Storage.Blobs/CHANGELOG.md. There it says:

Added support for token credential authentication using Azure.Identity library, including support for managed identity and client secret credentials.

But I'm not sure whether that's supported in Functions. @paulbatum or @kasobol-msft should have more details.

The documentation given below says it is possible:
https://docs.microsoft.com/en-us/samples/azure-samples/functions-storage-managed-identity/using-managed-identity-between-azure-functions-and-azure-storage/

But knowing the inconsistencies in the Azure libraries I won't be surprised that the above documentation does not mean it is available in the Azure functions with NodeJS. (and it might even differ for the Windows or Linux servers and for any random reasons. It is all a rabbit hole with dead ends. Just use the connection string and live with it if it is not possible to move to another cloud)

See https://github.com/Azure/azure-webjobs-sdk/issues/2575 for related conversation.

We have work currently in progress to make sure managed identity works end-to-end for this scenario (and other scenarios, such as service bus, eventhubs, etc) in Azure Functions. It will work for all languages. These changes rely on the work that Brett highlighted above, but there is more to do. Expect some more news in this area within the next few months.

I'm also interested in this scenario. We have security guidance to auto-rotate keys for storage accounts, but that's not a super feasible option given you would either have to manually go in and rotate the connection string in each Azure Function you own or write a separate tool to automate this. Using Managed Identity would resolve this issue for us.

@paulbatum I didn't see any updates on the thread you posted, is there any knowledge of when this feature might be on the roadmap?

Yep the work is in progress and should be available for use in a couple of months (hopefully we'll be able to communicate more precisely about the expected GA date once we have a preview of the full end-to-end available).

@paulbatum do you also happen to know if Durable Function TaskHub bindings will be included in the shift towards Managed Identity?

@michc-msft I believe this is a separate work item that the durable team has on their radar. Not sure if they have a tracking issue for it in github though. I took a quick look here and couldn't find one.

Just opened a feature request. Thanks for the pointer @paulbatum!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

paulbatum picture paulbatum  路  4Comments

silencev picture silencev  路  4Comments

ladeak picture ladeak  路  3Comments

ElvenSpellmaker picture ElvenSpellmaker  路  3Comments

JasonBSteele picture JasonBSteele  路  3Comments