Files
regorus/tests/azure_policy/cases/e2e_nsg_ssh_access.yaml
Anand Krishnamoorthi afdb894d85 test(azure_policy): add end-to-end policy test cases (#699)
50 end-to-end test cases derived from real Azure built-in policies. Each
file contains a complete policy definition, sample resources, and expected
evaluation results. Coverage spans storage, networking, compute, security,
monitoring, database, identity, governance, and update management scenarios.

Signed-off-by: Anand Krishnamoorthi <anakrish@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-27 18:04:50 -05:00

380 lines
13 KiB
YAML

# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# E2E Test: Network/NetworkSecurityGroup_SSHAccess_Audit
# Real Azure Policy: "[Deprecated]: SSH access from the Internet should be blocked"
# Source: regolator/policyDefinitions/Network/NetworkSecurityGroup_SSHAccess_Audit.json
#
# Features exercised:
# - Deeply nested template expressions: if(and(not(empty(...)), contains(...)))
# - Arithmetic in templates: int(), split(), first(), last()
# - Port range parsing: lessOrEquals/greaterOrEquals on split results
# - count with where clause + template expression
# - Double negation pattern: not { field notEquals "x" }
# - Parameterized effect with defaultValue
# - Multiple anyOf branches (destination port + source address)
aliases: test_aliases.json
policy_definition: |
{
"properties": {
"displayName": "[Deprecated]: SSH access from the Internet should be blocked",
"policyType": "BuiltIn",
"mode": "All",
"parameters": {
"effect": {
"type": "string",
"defaultValue": "Audit",
"allowedValues": ["Audit", "Disabled"]
}
},
"policyRule": {
"if": {
"allOf": [
{
"field": "type",
"equals": "Microsoft.Network/networkSecurityGroups/securityRules"
},
{
"allOf": [
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/access",
"equals": "Allow"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/direction",
"equals": "Inbound"
},
{
"anyOf": [
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
"equals": "*"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange",
"equals": "22"
},
{
"value": "[if(and(not(empty(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'))), contains(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'),'-')), and(lessOrEquals(int(first(split(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'), '-'))),22),greaterOrEquals(int(last(split(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRange'), '-'))),22)), 'false')]",
"equals": "true"
},
{
"count": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]",
"where": {
"value": "[if(and(not(empty(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')))), contains(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')),'-')), and(lessOrEquals(int(first(split(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')), '-'))),22),greaterOrEquals(int(last(split(first(field('Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]')), '-'))),22)) , 'false')]",
"equals": "true"
}
},
"greater": 0
},
{
"not": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]",
"notEquals": "*"
}
},
{
"not": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules/destinationPortRanges[*]",
"notEquals": "22"
}
}
]
},
{
"anyOf": [
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
"equals": "*"
},
{
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefix",
"equals": "Internet"
},
{
"not": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefixes[*]",
"notEquals": "*"
}
},
{
"not": {
"field": "Microsoft.Network/networkSecurityGroups/securityRules/sourceAddressPrefixes[*]",
"notEquals": "Internet"
}
}
]
}
]
}
]
},
"then": {
"effect": "[parameters('effect')]"
}
}
}
}
cases:
# =========================================================================
# Exact port 22 match
# =========================================================================
- note: audit_exact_port_22_from_internet
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "allow-ssh"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
sourceAddressPrefix: "Internet"
want_effect: "Audit"
- note: audit_exact_port_22_from_wildcard
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "allow-ssh-any"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
sourceAddressPrefix: "*"
want_effect: "Audit"
# =========================================================================
# Wildcard port (*)
# =========================================================================
- note: audit_wildcard_port_from_internet
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "allow-all"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "*"
sourceAddressPrefix: "Internet"
want_effect: "Audit"
# =========================================================================
# Port range containing 22
# =========================================================================
- note: audit_port_range_includes_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "allow-ssh-range"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "20-25"
sourceAddressPrefix: "*"
want_effect: "Audit"
- note: audit_port_range_exact_22_to_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "exactly-22"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22-22"
sourceAddressPrefix: "Internet"
want_effect: "Audit"
- note: audit_port_range_1_to_1024
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "low-ports"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "1-1024"
sourceAddressPrefix: "*"
want_effect: "Audit"
# =========================================================================
# Port range NOT containing 22
# =========================================================================
- note: pass_port_range_excludes_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "http-only"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "80-443"
destinationPortRanges: []
sourceAddressPrefix: "Internet"
sourceAddressPrefixes: []
want_undefined: true
- note: pass_port_23_only
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "port-23"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "23"
destinationPortRanges: []
sourceAddressPrefix: "*"
sourceAddressPrefixes: []
want_undefined: true
# =========================================================================
# destinationPortRanges[*] array — double negation pattern
# =========================================================================
- note: audit_port_ranges_array_contains_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "multi-port-ssh"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRanges:
- "80"
- "22"
- "443"
sourceAddressPrefix: "Internet"
want_effect: "Audit"
- note: audit_port_ranges_array_contains_wildcard
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "multi-port-wildcard"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRanges:
- "*"
sourceAddressPrefix: "*"
want_effect: "Audit"
- note: audit_port_ranges_array_with_range_containing_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "multi-port-range"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRanges:
- "80-443"
- "10-30"
sourceAddressPrefix: "Internet"
want_effect: "Audit"
- note: pass_port_ranges_array_no_22
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "non-ssh-ports"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRanges:
- "80"
- "443"
- "8080"
sourceAddressPrefix: "Internet"
want_undefined: true
# =========================================================================
# Source address variations
# =========================================================================
- note: audit_source_prefixes_array_wildcard
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "src-wild-array"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
sourceAddressPrefixes:
- "*"
want_effect: "Audit"
- note: audit_source_prefixes_array_internet
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "src-inet-array"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
sourceAddressPrefixes:
- "Internet"
want_effect: "Audit"
- note: pass_source_is_private_subnet
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "private-ssh"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
destinationPortRanges: []
sourceAddressPrefix: "10.0.0.0/8"
sourceAddressPrefixes: []
want_undefined: true
- note: pass_source_prefixes_all_private
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "private-array"
properties:
access: "Allow"
direction: "Inbound"
destinationPortRange: "22"
destinationPortRanges: []
sourceAddressPrefixes:
- "10.0.0.0/8"
- "172.16.0.0/12"
want_undefined: true
# =========================================================================
# Non-matching access / direction
# =========================================================================
- note: pass_deny_rule
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "deny-ssh"
properties:
access: "Deny"
direction: "Inbound"
destinationPortRange: "22"
sourceAddressPrefix: "*"
want_undefined: true
- note: pass_outbound_rule
resource:
type: "Microsoft.Network/networkSecurityGroups/securityRules"
name: "outbound-ssh"
properties:
access: "Allow"
direction: "Outbound"
destinationPortRange: "22"
sourceAddressPrefix: "*"
want_undefined: true
# =========================================================================
# Wrong resource type
# =========================================================================
- note: pass_wrong_type
resource:
type: "Microsoft.Storage/storageAccounts"
name: "not-nsg"
properties:
access: "Allow"
want_undefined: true