Skip to main content

Securing Blob Storage with SAS Tokens

Learn to generate scoped, time-limited Shared Access Signature tokens instead of sharing full Storage Account keys with external parties.

Overview and What You Will Learn

In this lab, you will generate a Shared Access Signature (SAS) token scoped to a single blob with read-only access and a short expiration window, then confirm it works exactly as scoped and stops working once it expires - demonstrating why a SAS token is the safer alternative to sharing a full Access Key.

Why This Matters in Production

A developer at a payments company like Razorpay hands a partner organization a full Storage Account Access Key so they can download one specific report file. That single key grants full read, write, and delete access to every blob in the entire account, not just the one file the partner actually needed - and it never expires until someone manually rotates it. A properly scoped SAS token would have given the partner exactly what they needed and nothing more.

Core Principles

Azure Storage offers two fundamentally different ways to grant access, and the difference in blast radius between them is significant.

◈ DIAGRAM
+------------------------+ +------------------------------+
| Access Key | | SAS Token |
| | | |
| Full account access | -------> | Scoped to a specific |
| Read, write, delete | | resource + permission set |
| everything, forever | | Expires automatically |
+------------------------+ +------------------------------+

A SAS token is generated with three things baked directly into it: which resource it applies to (a single blob, or an entire container), which permissions it grants (read-only, for example), and when it expires. Anyone holding the token can only do exactly what it allows, for exactly as long as it's valid.

Detailed Step-by-Step Practical Lab

  1. Create a Resource Group, Storage Account, and container, then upload a test file:
Bash
az group create --name rg-sas-lab-mumbai --location centralindia
az storage account create \
--name stsaslabrahul \
--resource-group rg-sas-lab-mumbai \
--location centralindia \
--sku Standard_LRS
az storage container create \
--name partner-reports \
--account-name stsaslabrahul
echo "monthly settlement report" > settlement.txt
az storage blob upload \
--account-name stsaslabrahul \
--container-name partner-reports \
--name settlement.txt \
--file settlement.txt
  1. Generate a SAS token scoped to only this one blob, with read-only permission, expiring in 24 hours:
Bash
az storage blob generate-sas \
--account-name stsaslabrahul \
--container-name partner-reports \
--name settlement.txt \
--permissions r \
--expiry $(date -u -d "24 hours" '+%Y-%m-%dT%H:%MZ') \
--output tsv
Note

--permissions r means read-only - the holder of this token cannot upload a new version, delete the blob, or list other blobs in the container. Only the exact action explicitly granted is possible.

  1. Construct the full URL using the blob's address plus the generated SAS token, and confirm it can be downloaded without any Azure credentials at all:
Bash
curl "https://stsaslabrahul.blob.core.windows.net/partner-reports/settlement.txt?<sas-token>"
  1. Attempt an action the token does not permit - like uploading a new file using that same token - and confirm it correctly fails, since the token was scoped to read-only on one specific blob.

  2. Generate a second SAS token with a very short expiration to observe expiration behavior directly:

Bash
az storage blob generate-sas \
--account-name stsaslabrahul \
--container-name partner-reports \
--name settlement.txt \
--permissions r \
--expiry $(date -u -d "2 minutes" '+%Y-%m-%dT%H:%MZ') \
--output tsv
  1. Wait a few minutes, then attempt to use that second token again - it should now be rejected as expired.

  2. Clean up:

Bash
az group delete --name rg-sas-lab-mumbai --yes --no-wait

Production Best Practices & Common Pitfalls

Security

Never share a Storage Account Access Key with an external party, a contractor, or a third-party application when a SAS token would accomplish the same goal. A leaked Access Key exposes the entire account indefinitely; a leaked SAS token exposes only what it was scoped to, only until it expires.

Tip

Set SAS token expiration windows as short as the actual use case allows. A token meant for a one-time file download does not need a 30-day expiration - a few hours is usually enough, and it meaningfully shrinks the window during which a leaked token could be misused.

  • Scope every SAS token to the narrowest resource possible. A token scoped to a single blob is safer than one scoped to an entire container, which is safer than one scoped to the whole account - always start narrow and only widen scope if genuinely necessary.
  • Rotating an Access Key invalidates every SAS token generated from it. This is a real operational consideration - if you rotate a key as part of routine security hygiene, any long-lived SAS tokens still in use elsewhere will stop working at the same time.

Quick Reference & Troubleshooting Commands

Command Description
az storage blob generate-sas Generate a SAS token scoped to one blob
az storage container generate-sas Generate a SAS token scoped to a whole container
az storage account keys list List the account's full Access Keys (use sparingly)
az storage account keys renew Rotate an Access Key, invalidating tokens generated from it

Explore More in Azure Storage Solutions

All 6 Topics

Frequently Asked Questions

Is Securing Blob Storage with SAS Tokens free to learn on DevOps Network?

Yes - this topic, like everything on DevOps Network, is 100% free with no paywall or sign-up gate.

What does the Securing Blob Storage with SAS Tokens topic cover?

Learn to generate scoped, time-limited Shared Access Signature tokens instead of sharing full Storage Account keys with external parties.