Stored Access Policies in Azure – Overview

Hello again folks. I’ve not posted in a while as I’ve just changed jobs and been spending the majority of time learning the ropes, as is customary 🙂

As my new role is primarily focused on Azure and Azure Stack, I’ve been putting together some ARM templates and walking through the Azure Portal as much as I can.

One of the features I’ve had fun getting to grips with is this idea of Stored access policies, so much so I thought I’d blog about it…so here goes.



Before we get into the details, what are Stored Access Policies and Shared Access Signatures (SAS) in Azure, and why do we care? It’s also worth mentioning that although this concept isn’t new or restricted to Azure, the Azure implementation is what we’re interested in here. Below are a few links to what’s being covered in this guide, the last link is a note of all PowerShell commands used in this guide with a brief explanation if that works better for you:



Part of this guide is going demo the streaming of a video file from a storage account in a browser (I’ve tested with both Edge and Chrome). You can view a test video file HERE, but we’ll download it from the web and upload it to our storage account later in the guide.


Shared Access Signature

A Shared Access Signature (SAS) is a URI that enables restricted access to entities within a storage account. This URI can then be passed to a client that requires access to a container or a single blob etc. within a storage account without having to give them a storage account key. Giving them a storage account key is basically giving them the keys to the kingdom as far as that storage account is concerned. When creating a SAS, the following properties can be set to control what can be accessed by it:

Which services can be accessed, these are:Blob
Which resource types can be accessed, these are:Service
Which permissions are given, chosen from:Read
Start Time and Expiry time of the SASSet a date and time for both. Also select a time zone
Allowed IPsThis can be a single IP or a hyphenated range of IPs
Allowed protocolsChoose between HTTPS or HTTPS and HTTP
Signing keyChoose which key to sign the SAS with, this will be chosen from one of the storage account keys

Here’s what this all looks like in the Azure portal:


Now SAS tokens are great, but they do have their limitations. What happens when you’ve generated a SAS token and passed it across to your client, the token then expires but you decide you want to extend their access for another couple of days. Well in this instance you’d have to generate another token for your client. Is there a way round this? Well that’s where Stored Access Policies come in 🙂


Stored Access Policies

So what are Stored Access Policies? Think of them as a way of grouping your service level SAS tokens by what services and resources they have access to. As these policies are on the server side, they can be modified without having to reissues SAS tokens that were generated from them.  They can also be revoked if required. Here’s an example:

You’ve created a Stored Access Policy that does the following:

  • Allows read access all blobs within a storage account container
  • Allows access for 14 days from its creation
  • Allows access from a single IP address, in this case the clients office IP

The client has advised you that they forgot to mention that they work out of two different offices depending on the day of the week. Now…because we generated the clients SAS token off the back of a Stored Access Policy, we can modify that policy to include the additional IP address specified by the client. The client will then be able to continue using that same SAS token, from their second office…cool right?


Creating a Stored Access Policy Using PowerShell

So now that we’ve went over things in a little detail, let’s get on and create something shall we?

I’m demonstrating doing this in PowerShell as doing it from the Azure portal doesn’t really require too much guidance and any that is you’ll find HERE 🙂

For this example I’ll be creating everything from scratch just to keep things straightforward and allow for easier deletion when we’re finished.

Let’s start by launching an editor like Visual Studio code or PowerShell ISE (elevated of course), I use VSC personally but use whatever works for you.

Before continuing (assuming you’ve not already done it), you’ll need to install Azure for PowerShell, you can find the instructions for that HERE

Now we’ll want to go ahead and log into our Azure account:


You’ll be prompted to enter your Azure AD credentials:



Once logged in, we’ll want to set our Azure context, i.e. select which subscription we’ll be working in.

The command below assumes you only have a single subscription, modify as required:

Set-AzureRMContext -SubscriptionId (Get-AzureRMSubscription).SubscriptionId


As I mentioned above, I’ll be creating everything we need from scratch here, so with that in mind let’s create a new resource group and storage account to work with.

$ResourceGroup = New-AzureRmResourceGroup -Name "Name for your Resource Group" -Location "Your chosen region"


Now that we’ve got a resource group, let’s give it a storage account.

$StorageAccount = New-AzureRmStorageAccount `
    -ResourceGroupName $ResourceGroup.ResourceGroupName `
    -Name "A name for your storage account" `
    -SkuName Standard_LRS `
    -Location $ResourceGroup.location

NOTE: Make sure that the name you give your storage account has no spaces or special characters and is all lowercase or it’ll be rejected.


Before we can continue, we’ll need to create a storage context to work in. To do this, we’ll need to grab the access keys for the storage account we just created.

$AccountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $StorageAccount.StorageAccountName


NOTE:  Yes I know I’ve shown you what the keys to my storage account are, but as I mentioned earlier, this account is for the purposes of this guide and will be deleted before it’s posted. Good eye though 🙂

Now let’s create our storage context

$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccount.StorageAccountName -StorageAccountKey $AccountKeys[0].Value


Now we’ll need to create a container in our storage account as we need somewhere to upload a test file and it’s the level we’ll be creating our Stored Access Policy against.

$StorageContainer = New-AzureStorageContainer -Name "Name for your container" -Context $StorageContext


Now let’s download a test video file from the web and upload it to our storage account container.

Invoke-WebRequest -Uri "" -OutFile C:\Temp\big_buck_bunny_720p_30mb.mp4
Set-AzureStorageBlobContent -File C:\Temp\big_buck_bunny_720p_30mb.mp4 -Container $StorageContainer.Name -Blob "Bunny720p.mp4" -Context $StorageContext -Properties @{"ContentType" = "video/mp4"}


Successful upload looks like:


Now that we’ve uploaded a file to our storage account container, let’s create that Stored Access Policy we’ve been talking about.

The following code will create a policy that gives us read access to blobs in our container for 5 hours from the policies creation time.

$SASPolicy = New-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy "DFTestSASPolicy" -Context $StorageContext -Permission "r" -StartTime (Get-Date).DateTime -ExpiryTime (Get-Date).AddHours(5).DateTime
Get-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy $SASPolicy -Context $StorageContext | FL

NOTE: For some reason I’ve yet to look into, the creation of the Storage Access Policy is not stored in the variable as an object, if just holds the name, hence the Get cmdlet afterwards to show you the details of the policy.



Testing and Validation Time

Now we’re in a position to create a Shared Access Signature (SAS) token (using our policy) that’ll give a user restricted access to the blobs in our storage account container.

The code below will create a SAS token, get the URI of the blob we uploaded to the account earlier, append it with the SAS token we created and copy the whole thing into the clipboard ready to be pasted in your browser of choice.

$SASToken = New-AzureStorageContainerSASToken -Name $StorageContainer.Name -Policy $SASPolicy.Policy -Context $StorageContext
(Get-AzureStorageBlob -Blob "Bunny720p.mp4" -Container $StorageContainer.Name -Context $StorageContext).ICloudBlob.Uri.AbsoluteUri + $SASToken | Clip

Pasting the contents of your clipboard into the address bar of a browser (tested with Edge and Chrome) should start streaming the video from your storage account.

The URL should look something like this:

I warn you now though, that video starts off all nice, but it gets pretty dark, pretty quick 🙂


NOTE:  Keep that URL in your clipboard for the time being, we’ll be needing it for the next few steps.

Now I said earlier that one of the benefits of using Stored Access Policies is that you can change the policy without invalidating the SAS token you provided to the end user…let’s prove that shall we.

The following PowerShell sets the Expiry date of our Stored Access Policy to be 30 minutes in the past

Set-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy $SASPolicy -Context $storageContext -ExpiryTime ((Get-Date).AddMinutes(-30))


Now if you paste the URL in your clipboard into the browser, or just refresh the page, you should see the following error.


Let’s set it back again just to complete the loop.

Set-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy $SASPolicy -Context $storageContext -ExpiryTime ((Get-Date).AddMinutes(30))


NOTE:  If you’ve misplaced the SAS token URL, you can retrieve it again with the following:

(Get-AzureStorageBlob -Blob "Bunny720p.mp4" -Container $StorageContainer.Name -Context $StorageContext).ICloudBlob.Uri.AbsoluteUri + $SASToken | Clip

Pasting it into the browser again, or refreshing the page, should start streaming the video…success!


…and that’s it for this guide folks. I hope this overview helps you get a better understanding of SAS tokens and policies in Azure. As promised at the start of this guide, I’ve listed all the commands I used together so you can grab them if that’s all you need 🙂

See you in the next guide.


PowerShell Commands Used in This Guide

# Log into Azure Account, you will be prompted for your credentials in a pop-up window

# Create a resource group, enter values for -ResourceGroupName and -Location
$ResourceGroup = New-AzureRmResourceGroup -Name "RG Name" -Location "Location"

# Create a storage account, enter value for -Name
$StorageAccount = New-AzureRmStorageAccount `
    -ResourceGroupName $ResourceGroup.ResourceGroupName `
    -Name "Storage Account Name" `
    -SkuName Standard_LRS `
    -Location $ResourceGroup.location

# Get the access keys of the Storage Account you just created
$AccountKeys = Get-AzureRmStorageAccountKey -ResourceGroupName $ResourceGroup.ResourceGroupName -Name $StorageAccount.StorageAccountName

# Create a storage context to work with the storage account you just created. It'll use the first access key on the account
$StorageContext = New-AzureStorageContext -StorageAccountName $StorageAccount.StorageAccountName -StorageAccountKey $AccountKeys[0].Value

# Create a container in the Storage Account you created earlier, enter value for -Name
$StorageContainer = New-AzureStorageContainer -Name "Container Name" -Context $StorageContext

# Download a sample mp4 video file and upload it to the Storage Account container you created earlier
Invoke-WebRequest -Uri "" -OutFile C:\Temp\big_buck_bunny_720p_30mb.mp4

Set-AzureStorageBlobContent -File C:\Temp\big_buck_bunny_720p_30mb.mp4 `
                            -Container $StorageContainer.Name `
                            -Blob "Bunny720p.mp4" `
                            -Context $StorageContext `
                            -Properties @{"ContentType" = "video/mp4"}

# Create a Stored Access Policy for the container you created earlier with read access to its blobs and an exiry time of 5 hours from the point of creation 
$SASPolicy = New-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name `
                                                         -Policy "DFTestSASPolicy" `
                                                         -Context $StorageContext `
                                                         -Permission "r" `
                                                         -StartTime (Get-Date).DateTime `
                                                         -ExpiryTime (Get-Date).AddHours(5).DateTime

# Create a SAS token using the policy you created earlier
$SASToken = New-AzureStorageContainerSASToken -Name $StorageContainer.Name `
                                              -Policy $SASPolicy `
                                              -Context $StorageContext

# Get the full URL including SAS token to access the video file you uploaded to the storage account earlier
(Get-AzureStorageBlob -Blob "Bunny720p.mp4" -Container $StorageContainer.Name -Context $StorageContext).ICloudBlob.Uri.AbsoluteUri + $SASToken | Clip

<# # Set the Stored Access Policy Expiry time to 30 minutes in the past Set-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy $SASPolicy -Context $storageContext -ExpiryTime ((Get-Date).AddMinutes(-30)) # Set the Stored Access Policy Expiry time to 30 minutes in the future Set-AzureStorageContainerStoredAccessPolicy -Container $StorageContainer.Name -Policy $SASPolicy -Context $storageContext -ExpiryTime ((Get-Date).AddMinutes(30)) #>

Leave a Reply

Your email address will not be published. Required fields are marked *