Create SAS token for Azure Data Lake directory in Powershell

610 Views Asked by At

I have a storage account in Azure which hosts a data lake. I want to authorize a specific directory with SAS token and I was able to do configure it by clicking in the portal. First of all, I created a stored access policy lets call it "external1". The policy does not define a permission or an expiry date, it is just used to be able to revoke the SAS token before the token expires.

After that, I navigated to the container "axexternal" to the directory "/external1/central" and generated a SAS token, defining the stored access policy, permissions and expiration date:

SAS token creation

These steps worked as expected. I need to re-create those SAS token automatically. I chose to use an Automation Account (Authorization by its Identity) and use Powershell script to execute the recreation. In detail, I recreate the Storage Access Key first, and then recreate the SAS token. Since the recreation of the Storage Access Key worked like a charm, I focus on the code of the SAS token recreation.

Unfortunatly the documenation for SAS token is technically available but poor. I am not sure which of the commandlets I have to use to get the same result as I had in the Azure Portal. Is it New-AzStorageAccountKey, New-AzStorageContainerSASToken, New-AzStorageBlobSASToken? None of the possible combination of parameters in the documentation seems to fit for my needs.

I need to pass these parameters to the appropriate commandllet:

  • Which storage access key to use for encryption
  • Stored Access Policy to use
  • Expiration Date
  • Permissions

Moreover, I am not able to understand the purpose of the -Context parameter in these commandlets. Is this context used to connect to the storage and execute the script for the creation of the SAS token or is it used to pass parameters to the commandlet? I tried many variations to achieve the goal, but I failed. Is there anybody able to give me some hints please?

Here is some code I tried:

$ctx = New-AzStorageContext `
    -StorageAccountName $storageAccount `
    -StorageAccountKey $key.Value `
    -Protocol "Https"

$uri = New-AzStorageBlobSASToken `
   -Context $ctx `
   -Container $container `
   -Blob "/external1/central" `
   -Policy $policy 
   -StartTime (Get-Date).AddDays(-1) `
   -ExpiryTime (Get-Date).AddDays(370) `
   -FullUri

Update

I recognized that my post was maybe too unspecific. I want to supplement it with a specific question.

Given

  • A data lake container named "axexternal"
  • A directory "/external1/central"
  • A stored access policy "external1" which does not define permissions or expiry date

Wanted

A Powershell script which creates a SAS for the specific directory "/external1/central" in the container "axexternal"

  • SAS signed by account key
  • SAS uses stored access policy "external1"
  • SAS defines permissions
  • SAS defines expiration date

Thanks for your help, I really appreciate!

2

There are 2 best solutions below

7
On

I tried in my environment and got successfully created azure SAS token with policy:

Initially I created access policy in portal like below:

enter image description here

I executed below command, and it created SAS token with URL successfully.

Command:

$accountname="venkat123"
$accountkey="<your storage account key >"
$containername="docker"
$blob="directory1/demo1mbimage.jpg"
$policy="external"

$ctx = New-AzStorageContext -StorageAccountName $accountName -StorageAccountKey $accountKey

 New-AzStorageBlobSASToken `
   -Context $ctx `
   -Container $containername `
   -Blob $blob `
   -Policy $policy `
   -FullUri

Console: enter image description here

I checked the file URL with browser it worked perfectly.

Browser:

enter image description here

Reference: New-AzStorageBlobSASToken (Az.Storage) | Microsoft Learn

0
On

After investigation I am now sure that currently it is not possible to get the exact same outcome using Powershell as you are able by using the Azure Portal.

The correct cmdlet to be used for my question is New-AzDataLakeGen2SasToken. That's the only way to be able to grant permission to a whole directory of a datalake.

Unfortunatly for this cmdlet there is no parameter to accept a stored access policy. For a datalake both APIs, datalake and BLOB is available for datalakes. As a consequence, the BLOB storage cmdlet New-AzStorageBlobSASToken works, but I didn't find a way to make it work on a directory. This seems to be consequent, since for BLOB storage, directories are just a part of a BLOB name.

Even if the permission to a single BLOB would be sufficient, it would not possible to use a Stored Access Policy which does not define permissions.

So I ended up using New-AzStorageBlobSASToken without using a Stored Access Policy. My plan for escaping problems when a SAS token got exploited is to rename the base folder and create new SAS tokens. This will be sufficient for my use case.

I use this kind of code now:

$container = "ext"
$centralPath = "external1/central"

$storageContext = New-AzStorageContext `
    -StorageAccountName $storageAccount `
    -StorageAccountKey $key.Value

New-AzDataLakeGen2SasToken `
    -Context $storageContext `
    -FileSystem $container `
    -Path $centralPath `
    -Permission "rdl" `
    -StartTime (Get-Date).AddDays(-1).Date `
    -ExpiryTime (Get-Date).AddDays(3).Date `
    -Protocol Https `
    -FullUri