Azure / Azure/azure-rest-api-specs

[BUG] HTTP 403 - UnauthorizedBlobOverwrite response while trying to overwrite an ADLS Gen2 directory with Userdelegation SAS token and only with ACLs permissions

Open
#32,708 0 comments 3 reactions 0 assignees View on GitHub
bug Data Lake Storage Gen2 Service Attention
Dominant language
TypeSpec
Stars
3.1k
Forks
5.9k
Avg merge
2d 22h
Merged PRs (30d)
444

Description

### API Spec link

https://learn.microsoft.com/en-us/rest/api/storageservices/datalakestoragegen2/path/create?view=rest-storageservices-datalakestoragegen2-2019-12-12

### API Spec version

2023-08-03

### Describe the bug

I have a service principal (SPN) that was granted the **Storage Blob Delegator** role at the account level to obtain a User Delegation Key (Microsoft.Storage/storageAccounts/blobServices/generateUserDelegationKey). I assigned only ACLs (no data-level RBAC permissions) to my SPN to traverse through the container and directories. Using SPN credentials, I generated a User Delegation SAS token and used it to create a directory under my storage container.

Here is the permission structure for my SPN:

- Account level RBAC: "Storage Blob Delegator"
- Container name: "aclvsrbac" --> R-X
- Directory name: "test" --> R-X
- Sub-directory name: "testdir" --> RWX

With these permissions, I was able to create a directory (testdir2) under "testdir". The initial call to create a directory was successful with an HTTP 201 status. However, subsequent calls with the same SAS token failed with a **403 – UnauthorizedBlobOverwrite** error when the "If-None-Match" header was set to "*". I expected an **HTTP 409 - The specified path already exists** error instead.

I need clarification from the Azure product team on why this behavior differs when using ACLs versus RBAC (storage blob data-level roles).

I want to add that this issue isn't only scoped for directory creation. Its also the similar for blob creation. We recomend customers to use ACLs for fine grain control of permissions but this discrepency in HTTP response code makes it hard for clients to troubleshoot/audit these kind of issues.

### Expected behavior

The subsequent CreatePath calls using the same user delegation SAS token with "If-None-Match" header set to "*" should result in HTTP **409 The specified path already exists** instead of HTTP **403 - UnauthorizedBlobOverwrite**.

### Actual behavior

Behaviour when only ACL permissions were given to SPN
=====================================

Initial call to create a directory

![Image](https://github.com/user-attachments/assets/2e665b1a-b8a0-4667-af2e-3f94646754dc)

Sub-sequent call failing with 403 - UnAuthorizedBlobOverwrite instead of 409 - The path already exists

![Image](https://github.com/user-attachments/assets/0c8300fe-4d44-4162-8b17-8da641b4dabe)

When SPN was given Blob Data level roles
============================
When my SPN was given "Storage Blob Data Contributor role" and generated user delegation SAS token following was the behaviour and its expected.

Initial call

![Image](https://github.com/user-attachments/assets/ebf6b240-9b41-406b-9fc9-7579ed84eca5)

Sub-sequent call (409 returned as expected)

![Image](https://github.com/user-attachments/assets/2beb550a-bed3-433e-9696-9eb68f6c5f7e)

### Reproduction Steps

```powershell
# Define the tenant ID for the Azure Active Directory
$tenantId = ""

# Define the client ID for the Azure AD application
$clientId = ""

# Define the client secret for the Azure AD application
$clientSecret = ""

# Convert the client secret to a secure string
$secureClientSecret = ConvertTo-SecureString $clientSecret -AsPlainText -Force

# Create a credential object using the client ID and secure client secret
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientId, $secureClientSecret

# Connect to Azure using the service principal credentials and tenant ID
Connect-AzAccount -ServicePrincipal -Credential $credential -Tenant $tenantId

# Create a storage context using the connected account and the specified storage account name
$ctx = New-AzStorageContext -StorageAccountName ganeshmstrggen2 -UseConnectedAccount

# Generate a SAS token for the specified storage container with read, add, create, write, delete, and list permissions, valid for up to 7 days from the current UTC time
New-AzStorageContainerSASToken -Context $ctx -Name "aclvsrbac" -Permission racwdl -ExpiryTime ""
```

### Environment

_No response_

Contributor guide

Open the contributing guide

Research direction

Start with the Data Lake Storage Gen2 Path/Create API specification linked in the issue, then run the PowerShell reproduction with ACL-only and RBAC permissions. Compare the documented and observed responses for repeated CreatePath or blob creation requests using If-None-Match: *, and consider the issue done when the service behavior is clarified or the API specification accurately documents the response difference.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, powershell
Domain
api, authorization, cloud
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.