Hello Scott Hietpas,
Welcome to the Microsoft Q&A and thank you for posting your questions here.
I understand that you are experiencing a PERMISSION_DENIED error in Azure Databricks when accessing files from an Azure Data Lake Storage Gen2 (ADLS) container, even though container-level Storage Blob Data Reader permissions have been granted.
The reason is because ADLS Gen2 enforces both Azure RBAC and POSIX-style Access Control Lists (ACLs). To resolve this without using broad account-level permissions, it’s crucial to configure the correct identity, scope, and ACLs at the container and directory levels.
First, identify the exact principal Databricks compute uses to access ADLS. Unity Catalog’s Explorer and compute workloads might use different identities typically, the Databricks Access Connector’s managed identity or a user-assigned managed identity linked to the storage credential. You can verify this by checking your Databricks External Location > Storage Credential settings or by reviewing storage access logs to confirm which principal ID performs read operations. - Databricks Access Connector Identity
Next, confirm the RBAC assignment at the container level. Use the Azure CLI to ensure the correct principal has the Storage Blob Data Reader role assigned at container scope:
az role assignment create \
--assignee <principal-object-id> \
--role "Storage Blob Data Reader" \
--scope /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<storageAccount>/blobServices/default/containers/<containerName>
- For a reference - Azure RBAC for Storage Data Access
Then, inspect and configure ADLS ACLs using:
az storage fs access show \
--account-name <storageAccount> \
--file-system <containerName> \
--path "<path/to/directory-or-file>" \
--auth-mode login
The compute identity must have execute (x) permission on every parent directory, read + execute (r-x) on the directory containing the data, and read (r--) on files. To apply these permissions, use:
az storage fs access set \
--account-name <storageAccount> \
--file-system <containerName> \
--path "path/to/directory" \
--acl "user:<objId>:r-x" \
--auth-mode login
For many files or folders, apply ACLs recursively with:
az storage fs access set-recursive \
--account-name <storageAccount> \
--file-system <containerName> \
--path "path/to/directory" \
--acl "user:<objId>:r-x" \
--auth-mode login
- For a more details - Manage ACLs for ADLS Gen2
After updating permissions, verify access directly from your Databricks notebook:
dbutils.fs.ls("abfss://<container>@<storageAccount>.dfs.core.windows.net/path/to/directory") spark.read.text("abfss://<container>@<storageAccount>.dfs.core.windows.net/path/to/file.csv").show(5)
If the issue persists, check Azure Storage diagnostic logs in Log Analytics to identify the denied principalId and specific path. This confirms whether ACLs are applied to the correct identity. - Monitor and Troubleshoot Azure Storage Access
Lastly, avoid granting account-level permissions as a long-term solution. Instead, maintain least-privilege by aligning RBAC with container scope, ensuring consistent ACL inheritance, and validating permissions on all parent directories. For complex directory structures, automate ACL propagation using scripts. - Azure Data Lake Storage Gen2 Best Practices
I hope this is helpful! Do not hesitate to let me know if you have any other questions or clarifications.
Please don't forget to close up the thread here by upvoting and accept it as an answer if it is helpful.