Enable Secure access to Azure Storage Account across multiple subscriptions
Published Apr 19 2021 04:47 AM 11.2K Views
Microsoft

Public read access to Azure containers and blob storage is an easy and convenient way to share data, however it also poses a security risk. For better and enhanced security, public access to the entire storage account can be disallowed regardless of the public access setting for an individual container present within the storage container. Disallowing public access to storage prevents a user from enabling public access for a container in the respective storage account.

Ensuring secure access to storage account(s) across subscriptions and storage accounts can be tedious as we grow. Here is a solution that can help you to disallow public access to storage account(s) at scale. You can extract the list of all storage accounts from the Azure subscription(s) and use the same .csv file as an input in the solution below to disallow access to storage account containers at scale across all your subscriptions.

 

Pre-Requisite:
 - Az Modules must be installed
 - Service Principal created as part of Step 1, must be having contributor level access to subscriptions
 
Steps to follow:
Step 1: Create a service principal
Post creation of service principal, please retrieve below values.
  1. Tenant Id
  2. Client Secret
  3. Client Id
 
Step 2: Create a PowerShell function which will be used in generating authorization token
function Get-apiHeader{
[CmdletBinding()]
Param
(
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $TENANTID,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $ClientId,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $PasswordClient,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $resource
)
$tokenresult=Invoke-RestMethod -Uri https://login.microsoftonline.com/$TENANTID/oauth2/token?api-version=1.0 -Method Post -Body @{"grant_type" = "client_credentials"; "resource" = "https://$resource/"; "client_id" = "$ClientId"; "client_secret" = "$PasswordClient" }
$token=$tokenresult.access_token
$Header=@{
  'Authorization'="Bearer $token"
  'Host'="$resource"
  'Content-Type'='application/json'
  }
return $Header
}
 
Step 3: Invoke API to retrieve authorization token using function created in above step
Note: Replace $TenantId, $ClientId and $ClientSecret with value captured in step 1
$AzureApiheaders = Get-apiHeader -TENANTID $TenantId -ClientId $ClientId -PasswordClient $ClientSecret -resource "management.azure.com"
 
Step 4: Extracting list of storage accounts across accessible subscriptions
$subscriptionList =  Get-AzSubscription
$subscriptionIdList = $subscriptionList.Id
foreach($subscriptionId in $subscriptionIdList)
{
$resourceURL = "https://management.azure.com/subscriptions/$($subscriptionId)/providers/Microsoft.Storage/storageAccounts?api-version=2021-01-01"
$resourcedetails=(Invoke-RestMethod  -Uri $resourceURL -Headers $AzureApiheaders -Method GET)
$TableData = $resourcedetails.value.ID
}

 

Step 5: Enable secure access to storage account
foreach($Data in $TableData)
{
  #Select Current Subscription and get All Storage Accounts
  $resourceid=$Data
  $resourceURL="https://management.azure.com$($resourceid)?api-version=2021-02-01"
  $resourcedetails=(Invoke-RestMethod  -Uri $resourceURL -Headers $AzureApiheaders -Method GET)
  $resourcelocation=$resourcedetails.location
  $permissions=$resourcedetails.properties.allowBlobPublicAccess
  if($permissions -eq $false)
  {
   Write-Output "Public access to Storage Account: $($resourcedetails.name) is already disabled"
  }
  Else 
  {
   Write-Output "Changing ACL for Storage Account: $($resourcedetails.name)" 
   $body = @"
   {
    "location":"$($resourcelocation)",
    "properties": {
         "allowBlobPublicAccess":  "false"
                  }
   }"@
   Invoke-RestMethod -Uri $resourceURL -Method Put -Headers $AzureApiheaders -Body $body 
  }
}

 

Overall Script:

function Get-apiHeader{
[CmdletBinding()]
Param
(
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $TENANTID,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $ClientId,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $PasswordClient,
 [Parameter(Mandatory=$true)]
 [System.String]
 [ValidateNotNullOrEmpty()]
 $resource
)
$tokenresult=Invoke-RestMethod -Uri https://login.microsoftonline.com/$TENANTID/oauth2/token?api-version=1.0 -Method Post -Body @{"grant_type" = "client_credentials"; "resource" = "https://$resource/"; "client_id" = "$ClientId"; "client_secret" = "$PasswordClient" }
$token=$tokenresult.access_token
$Header=@{
  'Authorization'="Bearer $token"
  'Host'="$resource"
  'Content-Type'='application/json'
  }
return $Header
}

$AzureApiheaders = Get-apiHeader -TENANTID $TenantId -ClientId $ClientId -PasswordClient $ClientSecret -resource "management.azure.com"

$subscriptionList =  Get-AzSubscription
$subscriptionIdList = $subscriptionList.Id

foreach($subscriptionId in $subscriptionIdList)
{
$resourceURL = "https://management.azure.com/subscriptions/$($subscriptionId)/providers/Microsoft.Storage/storageAccounts?api-version=2021-01-01"
$resourcedetails=(Invoke-RestMethod  -Uri $resourceURL -Headers $AzureApiheaders -Method GET)
$TableData = $resourcedetails.value.ID
foreach($Data in $TableData)
{
  #Select Current Subscription and get All Storage Accounts
  $resourceid=$Data
  $resourceURL="https://management.azure.com$($resourceid)?api-version=2021-02-01"
  $resourcedetails=(Invoke-RestMethod  -Uri $resourceURL -Headers $AzureApiheaders -Method GET)
  $resourcelocation=$resourcedetails.location
  $permissions=$resourcedetails.properties.allowBlobPublicAccess
  if($permissions -eq $false)
  {
   Write-Output "Public access to Storage Account: $($resourcedetails.name) is already disabled"
  }
  Else 
  {
   Write-Output "Changing ACL for Storage Account: $($resourcedetails.name)" 
   $body = @"
   {
    "location":"$($resourcelocation)",
    "properties": {
         "allowBlobPublicAccess":  "false"
                  }
   }"@
   Invoke-RestMethod -Uri $resourceURL -Method Put -Headers $AzureApiheaders -Body $body 
  }
}
}

 

References:

https://docs.microsoft.com/en-us/azure/storage/blobs/anonymous-read-access-configure?tabs=powershell

2 Comments
Version history
Last update:
‎Apr 23 2021 10:55 AM
Updated by: