01
Read the service error and preserve the original data
Record the HTTP status and storage error code without logging the full SAS URL. A 403 can have different causes, so use the code and request context rather than treating every failure as an invalid account key.
In the local test, overwriting with a read-only SAS returned 403 and left the original bytes unchanged. The same endpoint and blob accepted a subsequent token with the required write permission. That comparison isolated the operation’s permission contract.
02
Inspect the token’s intended resource and operation
Check whether the token targets the expected account, container, and blob, and whether its permission set matches the request. A token intended only for reading an existing blob is not an upload capability.
Creation, replacement, listing, and deletion are distinct operations. Choose permissions from the actual workflow rather than enabling every flag. Also verify time validity and any token restrictions before concluding that permissions alone explain the result.
03
Generate a limited replacement through an approved signer
This service-SAS function demonstrates the local lab contract using a supplied signing key. A deployed system should use its approved signing mechanism; Microsoft recommends user-delegation SAS where appropriate. Do not copy account keys into upload clients.
For the tested overwrite of one existing blob, write=True was sufficient. Other workflows can require different permissions. Regenerate the signature when changing the grant; editing the permission text in an existing signed token is not a valid repair.
from datetime import datetime, timedelta, timezone
from azure.storage.blob import BlobSasPermissions, generate_blob_sas
def make_test_overwrite_sas(account, container, blob, signing_key):
return generate_blob_sas(
account_name=account, container_name=container, blob_name=blob,
account_key=signing_key,
permission=BlobSasPermissions(write=True),
expiry=datetime.now(timezone.utc) + timedelta(minutes=10),
)04
Verify a controlled write and its result
Use a dedicated test blob or another explicitly intended destination. An overwrite can replace existing content, so first confirm the target and expected data. Keep the replacement SAS private and avoid echoing it in command output.
Our corrected overwrite produced the expected updated bytes, verified through a separate authorized read. A successful request alone was not the only check: we confirmed which blob changed and what it contained.
# sas_client targets only the intended test blob with the new SAS.
sas_client.upload_blob(b"expected-test-content", overwrite=True)
# Verify the intended bytes through an authorized read path.05
Investigate other authorization layers separately
If the required SAS permission is present but the request still fails, inspect the specific error, resource scope, validity window, network restrictions, and signing mechanism. An account can prohibit Shared Key authorization, and a user-delegation flow has its own identity requirements.
Keep the before/after service codes and non-sensitive operation description in the record. The local experiment proves this service-SAS permission distinction, not every authorization layer in an Azure deployment.
Know the limits
Reproduced with Azurite and azure-storage-blob 12.31.0 using API version 2023-11-03. A read-only service SAS could not overwrite a seeded blob; a write-enabled SAS could. Cloud RBAC, storage firewall rules, and user-delegation policy were not exercised.
Sources & further reading
A technical publication by CoreTrailKit.
Browse all articles