How to: check if a container exists without account level List permission
In a storage account, you can create a SAS scoped to a specific container, however, that SAS does not have permission to execute BlobClient.exists()
as this requires at least list
privileges on the parent object (e.g. the account), and when you try to perform the check, you’ll get this error:
azure.core.exceptions.HttpResponseError: This request is not authorized to perform this operation.
Note that this is an HttpResponseError
, not a ClientAuthenticationError
(which is actually a more specific error which extends HttpResponseError
), so you need to interrogate the specific response code, although note that if the container client does not exist, you might also get a ClientAuthenticationError
with this message
:
Server failed to authenticate the request. Make sure the value of Authorization header is formed correctly including the signature.\nRequestId:a52b0bdf-401e-0030-755f-fc3a0f000000\nTime:2024-09-01T11:09:19.0123125Z\nErrorCode:AuthenticationFailed\nauthenticationerrordetail:Signature did not match. String to sign used was rwl\n2022-01-01T00:00:00.0000000Z\n2030-01-01T00:00:00.0000000Z\n/blob/<account>/<container>\n\n\nhttps\n2015-04-05\nmax-age=5\ninline\ndeflate\n\napplication/json
As a workaround, you can instead try to read from or write to (depending on the privilege level you want to test for) the container. For example, you might do something like this:
def test_if_container_exists(container_client: ContainerClient) -> bool: """check if a container exists first by calling the .exists() method, even if the SAS scope is restricted to the specific container""" # first use the .exists() method to check if the container exists try: container_client.exists() return True except ClientAuthenticationError: # we dont know if this is because the SAS token doesnt have access or the container doesnt exist pass except HttpResponseError as e: if e.status_code == 404: return False elif e.status_code == 403: pass # could be a SAS token scope restriction except ResourceNotFoundError: return False except Exception as e: # if we got any other exception, raise it raise # if we got ClientAuthenticationError, try to write a small blob to check if the SAS token is valid try: blob_client = container_client.get_blob_client("test_blob") blob_client.upload_blob(b"Test content", overwrite=True) return True except ClientAuthenticationError or ResourceNotFoundError: return False except Exception as e: # if we got any other exception, raise it raise