Skip to main content
Five Steps for Cloud Compliance Readiness·A practical playbook for security teamsDownload
Guide · Microsoft Azure

How to block public access to Azure storage accounts

  • Updated 18 Oct 2026

This guide shows how to find Azure storage accounts that allow anonymous blob reads or accept traffic from any network, then close both gaps without breaking the apps that use them. It is written for Azure administrators who look after storage accounts across one or more subscriptions.

Before you start

Two separate settings decide whether a storage account is exposed. One controls anonymous reads of blob data. The other controls which networks can reach the public endpoint. This guide covers both.

  • Role to look: Reader on the subscriptions you want to review.
  • Role to change: a role that includes Microsoft.Storage/storageAccounts/write, such as Storage Account Contributor, Contributor or Owner, scoped to the storage account or higher.
  • Licences: none are needed for these settings.
  • Tools: the Azure portal and Azure CLI (az login first). Azure Resource Graph Explorer is handy for reviewing many accounts at once.
  • Make a list of apps first. Anything that reads blobs without credentials, or connects from an address you have not allowed, will stop working after the change.

Step by step

Steps 1 and 2 only read information. Steps 3 to 5 change the storage account and are marked CHANGE.

  1. List the accounts and their current setting (read-only). In the Azure portal open Resource Graph Explorer and run:
    resources
    | where type =~ 'Microsoft.Storage/storageAccounts'
    | extend allowBlobPublicAccess = parse_json(properties).allowBlobPublicAccess
    | extend publicNetworkAccess = parse_json(properties).publicNetworkAccess
    | extend defaultAction = parse_json(properties).networkAcls.defaultAction
    | project subscriptionId, resourceGroup, name, allowBlobPublicAccess, publicNetworkAccess, defaultAction
    An empty (null) allowBlobPublicAccess means the property was never set on that account, so treat it as not yet locked down.
  2. Find out who still reads anonymously (read-only). On each account that allows it, open Monitoring > Metrics, choose the Blob namespace and the Transactions metric, then filter Authentication equal to Anonymous. For detail, send the blob resource logs to a Log Analytics workspace through a diagnostic setting and run:
    StorageBlobLogs
    | where TimeGenerated > ago(7d) and AuthenticationType == "Anonymous"
    | project TimeGenerated, AccountName, AuthenticationType, Uri
    If a container really must be public, move it to its own storage account and leave that account out of this clean-up.
  3. CHANGE: disallow anonymous blob access. Portal: open the storage account, go to Settings > Configuration and set Allow Blob anonymous access to Disabled. Or with the CLI:
    az storage account update --name <storage-account> --resource-group <resource-group> --allow-blob-public-access false
    This overrides every container setting in the account. Allow up to 30 seconds for it to take effect. A static website in the $web container is not affected.
  4. CHANGE: add your allowed sources, then deny everything else. Add the networks that must keep access before you flip the default, so you do not lock yourself out:
    az storage account network-rule add --resource-group <resource-group> --account-name <storage-account> --ip-address <office-public-ip-or-cidr>
    az storage account network-rule add --resource-group <resource-group> --account-name <storage-account> --vnet-name <vnet> --subnet <subnet>
    az storage account update --name <storage-account> --resource-group <resource-group> --default-action Deny
    For a subnet rule to work, the subnet also needs the Azure Storage service endpoint. The portal creates it for you; the CLI does not.
  5. CHANGE (optional, strictest): turn off the public endpoint. If every client reaches the account through a private endpoint, set public network access to disabled:
    az storage account update --name <storage-account> --resource-group <resource-group> --public-network-access Disabled
    Do this only after the private endpoint and its DNS are working.
  6. Keep it that way. Assign an Azure Policy definition with the audit effect on Microsoft.Storage/storageAccounts/allowBlobPublicAccess first. Once the estate is clean, switch the effect to deny so new accounts cannot be created with public access.

Check it worked

These commands only read. Run them after the changes and expect the values shown.

az storage account show --name <storage-account> --resource-group <resource-group> --query "{anonymous:allowBlobPublicAccess, publicNetwork:publicNetworkAccess, defaultAction:networkRuleSet.defaultAction}" --output json
az storage account network-rule list --account-name <storage-account> --resource-group <resource-group>

You want anonymous to be false and defaultAction to be Deny (or publicNetwork to be Disabled). Then repeat the Resource Graph query from step 1 and confirm no account still shows true or an empty value. An anonymous request to a blob URL from a machine outside your allowed networks should now be refused.

Common mistakes

  • Setting Deny before adding your own IP or subnet, which cuts off your own admin access to the data plane.
  • Disabling anonymous access without checking the anonymous request metric, so a public download link or website asset quietly stops working.
  • Assuming an empty allowBlobPublicAccess means safe. It means the property was never set.
  • Adding an IP rule for a subnet that already uses a service endpoint. Traffic from that subnet uses a private source address, so the IP rule has no effect.
  • Turning off the public endpoint before private endpoint DNS resolves correctly.
  • Treating one account as the whole job. Repeat the review for every subscription.

How ConfigCobra helps

ConfigCobra is read-only: it never changes your Azure. Its Azure scan covers the CIS Microsoft Azure Foundations Benchmark v6.0.0 (127 controls) and three further Azure benchmarks, 339 controls in total, using Reader on your subscriptions and a certificate-based app registration. Each finding points at the exact Azure resource, and the Azure inventory has a built-in view of resources with public network access.

For a failing control, remediation impact analysis shows what would be affected before you apply the fix, with an impact level of High, Medium, Low or None. Scheduled scans with drift detection alert you by email when a control regresses, for example when someone re-enables anonymous access.

See where your Microsoft Azure stands

A read-only assessment against the CIS benchmarks, prioritised so you know what to fix first.

Get in touch

Let's talk.

Whether you're evaluating ConfigCobra, running an audit, or managing a client fleet — we respond within one business day.

Free trial