Skip to main content

Connect your own storage for Speech and Language services (Preview)

This article refers to the Microsoft Foundry (new) portal.
Items marked (preview) in this article are currently in public preview. This preview is provided without a service-level agreement, and we don’t recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Configure bring-your-own-storage (BYOS) for Speech and Language capabilities in a Foundry resource by setting the userOwnedStorage binding at creation time. This binding routes Speech and Language data to your Azure Storage account while maintaining backward compatibility with earlier standalone resource patterns.
Use this article when you specifically need Speech and Language data to land in storage you own. For the broader approaches (connections, capability hosts), see Connect to your own storage.

Prerequisites

An Azure account with an active subscription. If you don’t have one, create a free Azure account, which includes a free trial subscription.
  • An Azure Storage account (Blob) in a region supported by your Foundry resource.
  • Resource group permissions: Owner or Contributor role on the resource group containing the Foundry resource.
  • Storage account permissions: Storage Blob Data Contributor role on the storage account (assigned to the Foundry resource’s managed identity).
  • (Optional) Customer-managed keys (CMK) configured on the storage account if you require CMK encryption.
Set the userOwnedStorage binding when you create the resource. You can’t change this binding later. Review the restrictions before proceeding.

Understand restrictions

Review these constraints before configuring userOwnedStorage:
RestrictionDetails
Single accountYou can set only one storage account for Speech & Language.
Creation time onlyMust be set during resource creation; can’t add or change afterward.
Non-removableYou can’t remove or swap the storage account post-creation.
Deletion impactIf you delete or move the storage account (resource ID changes), Speech & Language stop functioning. Attempt storage account recovery first; otherwise you must recreate the Foundry resource.
Shared across both capabilitiesSpeech and Language share the same account (distinct containers). For strict isolation, create separate Foundry resources and storage accounts.
Data access scopeAny user with access to the Foundry resource can access Speech & Language outputs; project-level isolation doesn’t apply for this binding.

Configure authentication

Speech and Language support only Azure role-based access control (RBAC) through the resource’s managed identity.
  1. Ensure the Foundry resource has a system-assigned managed identity.
  2. On the storage account, assign the Storage Blob Data Contributor role to the Foundry resource’s managed identity.
  3. Don’t assign the role to individual project identities for this scenario.
API key–based authentication isn’t supported.

Example (Azure CLI) – role assignment

STORAGE_ID=/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storageName>
FOUNDRY_ID=/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<foundryName>

# Assign Storage Blob Data Contributor
az role assignment create \
  --assignee-object-id $(az resource show --ids $FOUNDRY_ID --query identity.principalId -o tsv) \
  --assignee-principal-type ServicePrincipal \
  --role "Storage Blob Data Contributor" \
  --scope $STORAGE_ID
If successful, the command returns a JSON object with the role assignment details including principalId and roleDefinitionId. Reference: az role assignment create | az resource show

Example (PowerShell) – role assignment

$storage = "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storageName>"
$foundry = "/subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<foundryName>"

$principalId = (Get-AzResource -ResourceId $foundry).Identity.PrincipalId
New-AzRoleAssignment -ObjectId $principalId -RoleDefinitionName "Storage Blob Data Contributor" -Scope $storage
If successful, the command returns a RoleAssignment object with the DisplayName, ObjectId, and Scope properties. Reference: New-AzRoleAssignment | Get-AzResource

Create resource with storage account

Set the userOwnedStorage field during resource creation.

Bicep template snippet

resource storage 'Microsoft.Storage/storageAccounts@2023-01-01' existing = {
  name: storageName
}

resource foundry 'Microsoft.CognitiveServices/accounts@2025-05-01-preview' = {
  name: foundryName
  location: location
  kind: 'AIServices'
  sku: { name: 'S0' }
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    userOwnedStorage: {
      storageResourceId: storage.id
    }
  }
}
Reference: Microsoft.CognitiveServices/accounts | Microsoft.Storage/storageAccounts

ARM template snippet

{
  "type": "Microsoft.CognitiveServices/accounts",
  "apiVersion": "2025-05-01-preview",
  "name": "[parameters('foundryName')]",
  "location": "[parameters('location')]",
  "kind": "AIServices",
  "identity": { "type": "SystemAssigned" },
  "sku": { "name": "S0" },
  "properties": {
    "userOwnedStorage": {
      "storageResourceId": "[resourceId('Microsoft.Storage/storageAccounts', parameters('storageName'))]"
    }
  }
}
Reference: Microsoft.CognitiveServices/accounts | ARM template functions

Terraform snippet

Refer to the Terraform cognitive_account documentation.
resource "azurerm_cognitive_account" "foundry" {
  name                = var.foundry_name
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
  kind                = "AIServices"
  sku_name            = "S0"

  # userOwnedStorage equivalent
  storage {
    resource_id = azurerm_storage_account.speechlang.id
  }

  identity {
    type = "SystemAssigned"
  }
}
Reference: azurerm_cognitive_account | azurerm_storage_account

Sample repository

See the infrastructure examples (including Speech/Language storage) in the Foundry samples repository.

Speech integration details

Speech scenarios (Speech-to-Text batch or real-time, Custom Speech, Text-to-Speech, Custom Voice) conform to the guidance in Bring your own storage (BYOS) Speech resource. When you set userOwnedStorage, those outputs route to the bound storage account containers.

Customer-managed keys (CMK)

If you configure customer-managed keys encryption on the storage account, Speech data written there uses those keys. If you don’t set userOwnedStorage, Speech falls back to Microsoft-managed storage and doesn’t inherit CMK settings from the Foundry resource.

Language integration details

The userOwnedStorage binding mirrors historical Language resource behavior with one key difference: you can’t update or replace the storage account after deletion or move. In standalone Language resources, an update is possible. In the unified Foundry resource, it isn’t. Plan lifecycle mitigation accordingly.

Shared storage configuration

Speech and Language share the same storage account. Different container naming conventions keep data logically separated. Because access is at the resource scope, any resource-level user can reach both sets of outputs. For stricter separation, deploy distinct resources.

Verify the configuration

After creating the resource with userOwnedStorage, confirm the binding is active:
  1. In the Azure portal, go to your Foundry resource.
  2. Select Resource Management > Properties and verify the User Owned Storage field displays your storage account resource ID.
  3. Run a test Speech or Language operation (for example, a batch transcription job) and confirm the output appears in a container within your storage account.
If the storage binding isn’t visible or operations fail, see the troubleshooting section.

Troubleshooting

IssueMitigation
Accidental deletion of storage accountAttempt recovering the account. If unsuccessful, recreate the Foundry resource.
Role assignment missingRe-run RBAC role assignment for the resource managed identity on the storage account.
Moved storage to new subscriptionRecreate resource; moving changes the resource ID and breaks binding.