Umbraco 13 connected to Azure Blob Storage through Azure Identity

Hello,
I am building an Umbraco 13 project and I need to connect to Blob Storage on Azure.
The Umbraco image is sitting inside an App Service and I tested to make sure Storage Blob Data Contributor role is assigned correctly so it can connect to Blob Storage.
Therefore Umbraco should connect to Blob Storage using Azure Identity package installed on the app. No ConnnectionString should be required.
Now I need to figure out how to indicate in Program.cs to Umbraco that it should identity the Blob Storage Container on Azure.
This is the code I have so far:

static void ConfigureBuilder(WebApplicationBuilder webAppBuilder, IConfiguration config)
{
IUmbracoBuilder builder = webAppBuilder.CreateUmbracoBuilder()
.AddBackOffice()
.AddWebsite()
.AddDeliveryApi()
.AddComposers()
.AddAzureBlobMediaFileSystem()
.AddAzureBlobImageSharpCache();

		webAppBuilder.Services.AddSingleton(sp =>
		{
			var accountUri = $"https://storageAccountName.blob.core.windows.net";
			var credential = new DefaultAzureCredential();
			var serviceClient = new BlobServiceClient(new Uri(accountUri), credential);
			var containerName = "storageAccountName-uat-media-storage";
			var containerClient = serviceClient.GetBlobContainerClient(containerName);
			return serviceClient.GetBlobContainerClient(containerName);
		});

ContainerName is the name of the container,
Uri is: https://storageAccountName.blob.core.windows.net
When I run the code locally, I don’t have access to blob storage, only when I publish the code to the development environment (sitting under an App Service in Azure).
When I run this either locally or in Azure I get 500.30 - ASP.NET Core app failed to start.

I asked various LLMs/chat bots:

  • first it told me to separate the accountUri from the container name like above.
  • then it hinted that I structured my Program.cs in a wrong way that doesn’t allow Umbraco to connect to Blob Storage via Azure Identity in time, so Umbraco fails to start returning 500.30 error as above

The nuget packages I am using are only Umbraco CMS and Azure Identity (latest versions at this time)
I also found a stack overflow post (non-umbraco related) that said it may be required to turn on Storage Blob Data Owner role also.
Has anyone ever managed to get Umbraco 13 with Blob Storage connected through Managed Identity on Azure?
Thanks!

Hi @raduorleanu ,

I checked with AI to find out what could be the issue. it gave me this, please check it out:

The reason you are hitting the 500.30 - ASP.NET Core app failed to start error is that Umbraco’s Azure Blob Storage extension (AddAzureBlobMediaFileSystem) does not automatically look for a BlobContainerClient registered via AddSingleton in the dependency injection container. Because the extension couldn’t find a valid connection string or credential passed directly into its own configuration pipeline, it threw an unhandled exception during the application startup phase.

To fix this, you need to configure the managed identity directly inside the .AddAzureBlobMediaFileSystem() options using the TryCreateBlobContainerClientUsingUri delegate. This feature was introduced to Umbraco.StorageProviders.AzureBlob specifically to bypass access keys and inject DefaultAzureCredential.

Here is the corrected code for your Program.cs:

using Azure.Identity;
using Azure.Storage.Blobs;

// ...

static void ConfigureBuilder(WebApplicationBuilder webAppBuilder, IConfiguration config)
{
    IUmbracoBuilder builder = webAppBuilder.CreateUmbracoBuilder()
        .AddBackOffice()
        .AddWebsite()
        .AddDeliveryApi()
        .AddComposers()
        .AddAzureBlobMediaFileSystem(options => 
        {
            // Pass the root Blob Storage endpoint as the connection string. 
            // The Umbraco provider is programmed to parse this as a URI rather than a key.
            options.ConnectionString = "https://storageAccountName.blob.core.windows.net";
            options.ContainerName = "storageAccountName-uat-media-storage";
            
            // This delegate intercepts the client creation and applies DefaultAzureCredential
            options.TryCreateBlobContainerClientUsingUri(uri => 
                new BlobContainerClient(uri, new DefaultAzureCredential())
            );
        })
        .AddAzureBlobImageSharpCache(); // Automatically inherits the configuration from the media file system

    // Note: You can completely remove the webAppBuilder.Services.AddSingleton(...) block 
    // you previously had, unless you need a standalone BlobServiceClient elsewhere for custom logic.
}

How This Works Behind the Scenes

When AddAzureBlobMediaFileSystem runs, it checks the ConnectionString property. If it detects a standard Azure connection string containing AccountKey=..., it uses traditional key-based authentication. However, if it detects a raw URI format (like https://...), it triggers the TryCreateBlobContainerClientUsingUri delegate instead.

By passing your DefaultAzureCredential into this delegate, Umbraco successfully authenticates using the App Service’s system-assigned managed identity in Azure without relying on external DI registrations.

Addressing the Azure IAM Roles

The Stack Overflow post you found suggesting the Storage Blob Data Owner role is inaccurate for this use case.

Storage Blob Data Contributor is the exact correct role you need. It grants the App Service identity full read, write, and delete access to blob containers and data. The “Owner” role only adds the ability to modify permissions and IAM roles on the storage account itself, which Umbraco does not do. Assigning Owner violates the principle of least privilege, so stick with Contributor.

Fixing Local Development

You mentioned that you do not have access to blob storage locally. If DefaultAzureCredential cannot find a valid token when you run the project on your local machine, the application will crash with the exact same 500.30 error because Umbraco expects the media file system to be available at boot.

To run this locally without relying on the cloud identity, you have two options: configure environment-specific app settings to fall back to the physical file system locally, or grant your personal Azure Active Directory account access to the blob storage container so DefaultAzureCredential works on your machine.

If you choose to authenticate locally to match the Azure environment:

1.Assign the IAM role to yourself:

In the Azure Portal, navigate to the Storage Account and assign the Storage Blob Data Contributor role to your personal user account (the email address you use to sign in to Azure).

2.Authenticate locally:

DefaultAzureCredential checks multiple sources for a token on your machine. Open your terminal and run az login using the Azure CLI, or sign into Visual Studio/Rider using that exact same Azure account.

3.Run the application:

Boot the project. The code will pick up your local developer credentials, generate an OAuth token, and successfully connect to the UAT storage account without throwing the 500.30 error.

Here’s some resources I found which has some documentation on this:
Official Umbraco Storage Providers Documentation github.com/umbraco/Umbraco.StorageProviders The primary README for this package explicitly documents how to use Azure.Identity to authenticate with Managed Identities. Scroll down to the configuration examples to see the exact implementation of TryCreateBlobContainerClientUsingUri alongside DefaultAzureCredential().

Umbraco GitHub Issue #43: Support for Managed Identities github.com/umbraco/Umbraco.StorageProviders/issues/43 This is the original feature request and pull request discussion where the Umbraco core team implemented TryCreateBlobContainerClientUsingUri specifically so developers could inject DefaultAzureCredential without rewriting the entire file system provider.

Hope it helps!

1 Like

Hi @ShekharTarare
Thank you for your help! I tried out your solution and I got it to work.

I’ll include the package versions for future reference:
Umbraco Cms 13.9.2
Umbraco StorageProviders AzureBlob 13.1.0
Azure Identity 1.21.0
Azure Storage Blobs 12.22.1

Thanks again for all your help!

1 Like