Azure Network Security Perimeter, or NSP, is one of the most important additions to Azure’s network security model for organizations that want tighter control over access to their protected resources.
At a high level, NSP helps you define a boundary around a set of Azure resources and apply security rules that govern who and what can connect to them. Instead of relying only on traditional network controls, you can add an additional layer of protection that focuses on the resource itself.
This is especially useful when you are working with services such as Azure Storage, Azure Key Vault, or other PaaS resources that might otherwise be exposed by broad network access policies.
Why NSP matters
The main benefit of NSP is simplicity. You can apply a consistent access model to a group of resources without having to redesign the entire network topology. It complements existing tools such as private endpoints, VNets, and firewalls by giving you a resource-centric control plane.
For many teams, this means:
- Better control over inbound traffic to protected resources
- A clearer security posture for shared Azure environments
- Easier enforcement of least-privilege connectivity rules
- Stronger governance for multi-team or multi-subscription architectures
What makes NSP different
Traditional network security often focuses on network segments, subnets, or IP ranges. NSP shifts part of the conversation to the resources themselves. That makes it easier to reason about the security boundary around a target service and to prevent unnecessary exposure.
In practice, this can help organizations reduce the attack surface and make access decisions more explicit.
A simple Bicep example
A minimal starting point for an NSP deployment can look like this:
targetScope = 'resourceGroup'
@description('Name of the network security perimeter')
param perimeterName string = 'contoso-platform-prod-nsp'
@description('Environment tag applied to the perimeter')
param environment string = 'prod'
@description('Resource IDs that should be protected by the perimeter')
param protectedResourceIds array = [
'/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-platform-prod/providers/Microsoft.Storage/storageAccounts/stprodshared001'
'/subscriptions/00000000-0000-0000-0000-000000000000/resourceGroups/rg-platform-prod/providers/Microsoft.KeyVault/vaults/kv-platform-prod'
]
resource perimeter 'Microsoft.Network/networkSecurityPerimeters@2024-05-01' = {
name: perimeterName
location: 'global'
tags: {
Environment: environment
Owner: 'Platform Engineering'
SecurityBoundary: 'Production'
}
properties: {
// Example rule shape for a production deployment
accessRules: [
{
name: 'allow-platform-engineering'
properties: {
direction: 'Inbound'
access: 'Allow'
description: 'Allow management traffic from the platform engineering subnet'
addressPrefixes: [
'10.20.30.0/24'
]
destinationPortRanges: [
'443'
]
}
}
]
// In a production deployment, define resource links and policy
// associations here as well.
}
}
output perimeterId string = perimeter.id
output protectedResourceCount int = length(protectedResourceIds)
This example is intentionally simple. In a real deployment, you would extend it with the resources you want to protect and the access rules that define who can reach them.
A good first step
If you are evaluating Azure security controls, NSP is a strong topic to explore early. It is a practical feature for teams that want to modernize their Azure landing zone and strengthen protection around critical services without adding excessive operational complexity.
In the next article, I will focus on how to apply NSP to PaaS resources and what the first implementation steps look like.
Azure
Network Security Perimeter
Comments
Post comment