App to Blob Storage with a managed identity

The handoff from an App Service, Functions, Container Apps or VM workload to Blob or Data Lake storage without keys — user-assigned identity, Storage Blob Data Contributor at the container, Shared Key off, a network path that works for same-region callers (VNet rule or private endpoint, not an IP rule), BlobServiceClient with ManagedIdentityCredential — with known-bad configurations, their exact error codes, and which side is wrong.

markdownpatternv12GNJ-V717stage: buildtrust: officialtrust: fieldservice: storageservice: managed-identityservice: rbacinterface: iacinterface: sdkinterface: cliApp Service Blob Storage managed identityFunctions storage managed identityContainer Apps storage managed identityStorage Blob Data Contributor managed identityAuthorizationPermissionMismatch managed identityKeyBasedAuthenticationNotPermitted connection stringAuthorizationFailure App Service same regionstorage IP rule App Service outbound IPstorage private endpoint App ServiceManagedIdentityCredential BlobServiceClientwhich side is wrong storage

Created 21 Oct 2026 · Modified 23 Oct 2026 · 1 version

App side: the app runs as a managed identity and asks for a token for https://storage.azure.com. Storage side: the account's network lets the app in, then a data role on the account or container grants the operation. Every failure below is one of those, and the error code tells you which.

Known-good

  • A user-assigned identity id-orders, attached to the app; its client ID in the app setting APP_IDENTITY_CLIENT_ID.
  • Storage Blob Data Contributor for the identity's principalId on the container (or account), principalType: ServicePrincipal, guid() name. Reader if it only reads.
  • Account: allowSharedKeyAccess: false, minimumTlsVersion: 'TLS1_2', allowBlobPublicAccess: false (guides/storage/create-secure-storage-account.md).
  • Network, for an app in the same region: VNet integration into a subnet that has the Microsoft.Storage service endpoint and a VNet rule on the account; or publicNetworkAccess: Disabled with a private endpoint for blob (and dfs for Data Lake) and the privatelink.blob.core.windows.net zone linked to the app's VNet.
  • Code: new BlobServiceClient("https://<acct>.blob.core.windows.net", new ManagedIdentityCredential({ clientId: process.env.APP_IDENTITY_CLIENT_ID })), one client per process (guides/storage/access-blobs-from-typescript.md).

Setting up the identity: guides/managed-identity/use-managed-identity.md. Assigning the role: guides/rbac/assign-roles.md.

Known-bad

ConfigurationSymptom
Identity holds Owner or Contributor on the account, no data role403 AuthorizationPermissionMismatch This request is not authorized to perform this operation using this permission.
Role assigned a minute agoSame 403 for 10–30 minutes, then it works
Role on a group containing the identitySame 403 for hours: managed identity tokens are cached (about 24 h) with the group memberships they were issued with
App still uses a connection string after Shared Key was turned off403 KeyBasedAuthenticationNotPermitted Key based authentication is not permitted on this storage account.
Firewall defaultAction: Deny with the app's outbound IPs in ipRules, app in the same region403 AuthorizationFailure This request is not authorized to perform this operation.: same-region traffic arrives on private addresses, so IP rules never match
Relying on bypass: AzureServices for App Service or FunctionsSame AuthorizationFailure: they aren't trusted services
Private endpoint created, DNS zone not linked to the app's VNetThe name resolves to the public IP: AuthorizationFailure if public access is denied, or a timeout
Data Lake account with only a blob private endpointDirectory and ACL operations through dfs fail
Two user-assigned identities, DefaultAzureCredential with no client IDToken for the wrong identity or none: 403, or ManagedIdentityCredential errors
Custom HTTP code requests a token for another audience (for example https://management.azure.com)401 Server failed to authenticate the request. Please refer to the information in the www-authenticate header.

Which side is wrong

  • No token (ManagedIdentityCredential…, IMDS or IDENTITY_ENDPOINT errors) → the app: identity attached, right client ID (reference/managed-identity/errors.md).
  • 401 → the token's audience. Use the SDK; the scope is https://storage.azure.com/.default.
  • 403 AuthorizationFailure → the storage account's network: firewall, public network access, private endpoint DNS (reference/storage/network-and-firewall.md).
  • 403 AuthorizationPermissionMismatch → the role: missing, on Owner/Contributor only, on a group, not propagated, or (Data Lake, no role) a missing ACL Execute on a parent.
  • 403 KeyBasedAuthenticationNotPermitted → the app's configuration still uses a key or a non-user-delegation SAS.

az storage account show -n <acct> --query "{public:publicNetworkAccess, firewall:networkRuleSet, sharedKey:allowSharedKeyAccess}" answers the storage-side questions in one call; az role assignment list --assignee <principal-id> --all -o table answers the role question.

Read this document as markdown — the same bytes an agent receives.