Workload Identity Federation for Azure Blob Storage integrations

This topic describes how to configure a Snowflake storage integration for Azure Blob Storage using Workload Identity Federation (WIF). With WIF, Snowflake uses an OpenID Connect (OIDC) trust relationship with a user-assigned managed identity instead of a shared access signature or account key, so there are no long-lived credentials to manage.

Prerequisites

  • Access to an Azure subscription with permissions to create managed identities and assign RBAC roles.
  • An Azure Blob Storage account and container that you want Snowflake to access.
  • A Snowflake account with a role that has the CREATE INTEGRATION privilege (for example, ACCOUNTADMIN).

Step 1: Find your Azure AD tenant ID

Find your Azure AD directory (tenant) ID before configuring the integration. Sign in to the Azure portal and select Azure Active Directory > Properties. The tenant ID is displayed in the Tenant ID field.

You provide this value as AZURE_TENANT_ID when you create the storage integration.

Step 2: Create a managed identity

If you don’t already have a user-assigned managed identity for Snowflake to assume, create one in your Azure subscription.

  1. In the Azure portal, navigate to Managed Identities and select Create.
  2. Select your subscription and resource group, choose a region, and provide a name for the identity.
  3. Select Review + create, then Create.
  4. After creation, note the Client ID from the identity’s overview page. This is the value you provide as AZURE_CLIENT_ID when creating the storage integration.

Step 3: Create the storage integration in Snowflake

To create a WIF-enabled storage integration in Snowflake, run the following SQL:

CREATE OR REPLACE STORAGE INTEGRATION my_azure_wif_integration
    TYPE = EXTERNAL_STAGE
    STORAGE_PROVIDER = AZURE
    AUTH_TYPE = WORKLOAD_IDENTITY_FEDERATION
    AZURE_TENANT_ID = '<your-azure-ad-tenant-id>'
    AZURE_CLIENT_ID = '<client-id-of-your-managed-identity>'
    STORAGE_ALLOWED_LOCATIONS = ('azure://<account>.blob.core.windows.net/<container>/')
    ENABLED = TRUE;

Replace the following values:

  • <your-azure-ad-tenant-id> — Your Azure AD directory (tenant) ID.
  • <client-id-of-your-managed-identity> — The client ID of a user-assigned managed identity in your Azure subscription. If you have not yet created one, see Step 2: Create a managed identity.
  • <account> — Your Azure storage account name.
  • <container> — The blob container name.

To optionally override the default federation audience, add the WORKLOAD_IDENTITY_FEDERATION_AUDIENCE parameter:

CREATE OR REPLACE STORAGE INTEGRATION my_azure_wif_integration
    TYPE = EXTERNAL_STAGE
    STORAGE_PROVIDER = AZURE
    AUTH_TYPE = WORKLOAD_IDENTITY_FEDERATION
    AZURE_TENANT_ID = '<your-azure-ad-tenant-id>'
    AZURE_CLIENT_ID = '<client-id-of-your-managed-identity>'
    WORKLOAD_IDENTITY_FEDERATION_AUDIENCE = 'api://my-custom-audience'
    STORAGE_ALLOWED_LOCATIONS = ('azure://<account>.blob.core.windows.net/<container>/')
    ENABLED = TRUE;

Step 4: Retrieve the WIF issuer and subject

After creating the integration, retrieve the federation parameters that you need for the Azure-side configuration:

DESC STORAGE INTEGRATION my_azure_wif_integration;

Record the values of the following properties from the output:

  • WORKLOAD_IDENTITY_FEDERATION_ISSUER — The OIDC issuer URL for Snowflake’s identity provider. Use this as the issuer when creating the FIC.
  • WORKLOAD_IDENTITY_FEDERATION_SUBJECT — A unique subject identifier for this integration. Use this as the subject when creating the FIC.
  • WORKLOAD_IDENTITY_FEDERATION_AUDIENCE — The audience value (defaults to api://AzureADTokenExchange). Use this as the audiences entry in the FIC.

Important

The subject value is unique to each integration and is regenerated if you drop and recreate the integration. If you recreate the integration, you must update the FIC with the new subject.

Step 5: Create the federated identity credential

To establish trust between Azure AD and Snowflake’s OIDC issuer, create a Federated Identity Credential (FIC) on the managed identity.

  1. In the Azure portal, navigate to your managed identity.
  2. Under Settings, select Federated credentials.
  3. Select Add Credential.
  4. For Federated credential scenario, select Other issuer.
  5. Fill in the following fields:
    • Issuer — The WORKLOAD_IDENTITY_FEDERATION_ISSUER value from DESC STORAGE INTEGRATION.
    • Subject identifier — The WORKLOAD_IDENTITY_FEDERATION_SUBJECT value from DESC STORAGE INTEGRATION.
    • Audience — The WORKLOAD_IDENTITY_FEDERATION_AUDIENCE value (defaults to api://AzureADTokenExchange).
    • Name — A descriptive name for the credential, for example snowflake-wif-credential.
  6. Select Add.

Alternatively, use the Azure CLI:

az identity federated-credential create \
    --name snowflake-wif-credential \
    --identity-name my-snowflake-wif-identity \
    --resource-group my-resource-group \
    --issuer '<WORKLOAD_IDENTITY_FEDERATION_ISSUER value>' \
    --subject '<WORKLOAD_IDENTITY_FEDERATION_SUBJECT value>' \
    --audiences 'api://AzureADTokenExchange'

Step 6: Assign RBAC roles to the managed identity

Grant the managed identity access to your storage account. Two role assignments are required:

  • Storage Blob Data Contributor — Scoped to the container. Grants read/write access to blob data.
  • Storage Blob Delegator — Scoped to the storage account. Required because Snowflake uses User Delegation SAS tokens, which call the storage-account-level Get User Delegation Key API.

Important

The Storage Blob Delegator role must be assigned at the storage account scope, not the container scope. Assigning it at the container scope results in AuthorizationPermissionMismatch errors.

To assign the roles in the Azure portal:

  1. Navigate to your storage account.
  2. Select Access Control (IAM) and then Add role assignment.
  3. Search for and select Storage Blob Delegator, then select Next.
  4. Under Members, select Managed identity, then select your managed identity.
  5. Select Review + assign.
  6. Repeat steps 2 through 5 for the Storage Blob Data Contributor role, this time scoped to the specific container. Navigate to Containers > your container > Access Control (IAM), then add the role assignment there.

Alternatively, use the Azure CLI:

# Storage Blob Delegator at the storage account scope
az role assignment create \
    --assignee-object-id "$(az identity show --name my-snowflake-wif-identity --resource-group my-resource-group --query principalId -o tsv)" \
    --assignee-principal-type ServicePrincipal \
    --role "Storage Blob Delegator" \
    --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>"

# Storage Blob Data Contributor at the container scope
az role assignment create \
    --assignee-object-id "$(az identity show --name my-snowflake-wif-identity --resource-group my-resource-group --query principalId -o tsv)" \
    --assignee-principal-type ServicePrincipal \
    --role "Storage Blob Data Contributor" \
    --scope "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Storage/storageAccounts/<storage-account>/blobServices/default/containers/<container>"

Step 7: Wait for Azure AD propagation

Azure AD replicates FIC and RBAC assignments asynchronously. After completing the Azure-side configuration, wait approximately 45 to 60 seconds before attempting to use the integration. During propagation, you may see errors like:

  • AADSTS700213 or AADSTS70021 — “No matching federated identity record found.” The FIC has not yet propagated.
  • AuthorizationPermissionMismatch — The RBAC role assignment has not yet propagated.

These errors resolve without intervention once propagation completes.

Step 8: Verify the integration (optional)

After the propagation window, verify that the integration works by creating an external stage and listing its contents:

CREATE OR REPLACE STAGE my_azure_wif_stage
    STORAGE_INTEGRATION = my_azure_wif_integration
    URL = 'azure://<account>.blob.core.windows.net/<container>/';

LIST @my_azure_wif_stage;

A successful LIST command that returns your container’s contents confirms that the end-to-end WIF trust chain is working.

Limitations and considerations

During Private Preview, the following limitations apply:

  • Cross-cloud and cross-partition configurations aren’t supported.
  • Reads from a replicated storage integration on the replicated secondary aren’t supported. Reads work after the secondary becomes the primary.
  • Sovereign and federated clouds aren’t supported.